pthread库实现一个简单的任务池
说明:
1:TaskManager类管理Task类,Task类是一个纯虚类;
2:ThreadManager类管理Thread类,Thread类封装pthread库的相关线程函数;
3:Thread类通过TaskManager类获取需要执行的任务;
4:ThreadManager类中包含一个TaskManager用于管理需要其管理线程执行的Task;
5:UserTask是用户继承Task类而来的用户自己的任务类,最后线程池中运行的任务就是UserTask。
该交代的都交代了,现在上代码。^-^
Task.h
/**********************
* author: zhanghang
* date: 2016.02.27
* file: Task.h
* usage: this is the pure virtual base class of the task in the task pool
***********************/ #ifndef _TASK_H
#define _TASK_H #define TIMES_OF_SLEEP_ONE_SEC 1500000 class Task
{
public:
Task(){};
virtual ~Task(){};
virtual void Process() = 0;
// all the delay operations should use this function
void Delay(int sec)
{
for(int i=0; i<sec; ++i)
{
for(int j=0; j<TIMES_OF_SLEEP_ONE_SEC; ++j)
{
}
}
}
}; #endif
自己封装了一个锁类,GuardLock.h
/************************
* author: zhanghang
* date: 2016.02.27
* file: GuardLock.h
* usage: this class to lock a code scope
************************/ #ifndef _GUARD_LOCK_H
#define _GUARD_LOCK_H #include <pthread.h>
#include <iostream> class GuardLock
{
public:
GuardLock(pthread_mutex_t *pMutex):m_pMutex(pMutex)
{
pthread_mutex_lock(m_pMutex);
}
~GuardLock()
{
pthread_mutex_unlock(m_pMutex);
}
private:
pthread_mutex_t *m_pMutex;
}; #endif
TaskManager.h
/************************
* author: zhanghang
* date: 2016.02.27
* file: TaskManager.h
* usage: this class is to manage the tasks
***********************/ #ifndef _TASK_MANAGER_H
#define _TASK_MANAGER_H #include <pthread.h>
#include <list>
class Task; class TaskManager
{
public:
TaskManager();
~TaskManager();
void AddTask(Task *pTask);
void DeleteAllTask();
int GetTaskNum();
Task *GetATask();
private:
std::list<Task *> m_TaskList;
pthread_mutex_t m_AccTaskListMutex;
}; #endif
TaskManager.cpp
/************************
* author: zhanghang
* date: 2016.02.27
* file: TaskManager.cpp
* usage: this class is to manage the tasks
***********************/ #include "GuardLock.h"
#include "TaskManager.h"
#include "Task.h"
#include <iostream> TaskManager::TaskManager()
{
std::cout << "TaskManager::TaskManager*" << (void *)this << std::endl;
} TaskManager::~TaskManager()
{
std::cout << "TaskManager::~TaskManager#" << (void *)this << std::endl; if(m_TaskList.size() > 0)
{
DeleteAllTask();
}
} void TaskManager::AddTask(Task *pTask)
{
GuardLock lock(&m_AccTaskListMutex); if(NULL != pTask)
{
m_TaskList.push_back(pTask);
}
} void TaskManager::DeleteAllTask()
{
GuardLock lock(&m_AccTaskListMutex); std::list<Task *>::iterator taskItr = m_TaskList.begin();
while(m_TaskList.end() != taskItr)
{
delete *taskItr;
++taskItr;
}
m_TaskList.clear();
} int TaskManager::GetTaskNum()
{
return m_TaskList.size();
} Task *TaskManager::GetATask()
{
GuardLock lock(&m_AccTaskListMutex); Task *pTask = NULL;
std::list<Task *>::iterator taskBeg = m_TaskList.begin();
if(m_TaskList.end() != taskBeg)
{
pTask = (*taskBeg);
m_TaskList.erase(taskBeg);
}
return pTask;
}
Thread.h
/************************
* author: zhanghang
* date: 2016.02.27
* file: Thread.h
* usage: this class is to new a thread
***********************/ #ifndef _THREAD_H
#define _THREAD_H #include <pthread.h> #define TIMES_OF_SLEEP_ONE_SEC 1500000 class Task;
class TaskManager; // the entrance of the new thread
void *ThreadMain(void *pArg); class Thread
{
public:
Thread(TaskManager &taskManager);
~Thread();
int Run();
int Stop();
bool IsFree();
// because there is one cnacel point in the sleep func
// so i write my own delay func
void Delay(int sec); friend void *ThreadMain(void *pArg);
private:
bool m_IsFree;
bool m_ExitFlag;
Task *m_pTask;
TaskManager &m_TaskMgr;
pthread_t m_ThreadID;
}; #endif
Thread.cpp
/************************
* author: zhanghang
* date: 2016.02.27
* file: Thread.cpp
* usage: this class is to new a thread
***********************/ #include "Thread.h"
#include "Task.h"
#include "TaskManager.h"
#include <iostream> Thread::Thread(TaskManager &taskMgr)
: m_IsFree(true), m_ExitFlag(false), m_pTask(NULL), m_TaskMgr(taskMgr), m_ThreadID(0)
{
std::cout << "Thread::Thread*" << (void *)this << std::endl;
} Thread::~Thread()
{
std::cout << "Thread::~Thread#" << (void *)this << std::endl; if(!m_ExitFlag)
{
m_ExitFlag = true;
}
} int Thread::Run()
{
return pthread_create(&m_ThreadID, NULL, ThreadMain, this);
} int Thread::Stop()
{
m_ExitFlag = true;
void *pRet = NULL;
pthread_cancel(m_ThreadID);
return pthread_join(m_ThreadID, &pRet);
} bool Thread::IsFree()
{
return m_IsFree;
} void Thread::Delay(int sec)
{
for(int i=0; i<sec; ++i)
{
for(int j=0; j<TIMES_OF_SLEEP_ONE_SEC; ++j)
{
}
}
} // thre entrance of thread
void *ThreadMain(void *pArg)
{
if(NULL == pArg)
{
return NULL;
} // set the cancel state to enable
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
// set the cancel type to run to next cnacel point
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); Thread &rThread = *((Thread *)pArg); while(!rThread.m_ExitFlag)
{
rThread.m_pTask = rThread.m_TaskMgr.GetATask(); // there is no task
if(NULL == rThread.m_pTask)
{
rThread.m_IsFree = true;
//sleep(1); // do not use sleep function, there is some cancel point in the function
rThread.Delay(1);
continue;
} rThread.m_IsFree = false;
// the mission
rThread.m_pTask->Process(); // clear the task room
delete rThread.m_pTask;
rThread.m_pTask = NULL; // set a cancel point
pthread_testcancel();
}
}
ThreadManager.h
/************************
* author: zhanghang
* date: 2016.02.07
* file: ThreadManager.h
* usage: this class is to manage the threads
*******************************/ #ifndef _THREAD_MANAGER_H
#define _THREAD_MANAGER_H #include <list>
class Task;
class Thread;
class TaskManager; class ThreadManager
{
public:
ThreadManager();
~ThreadManager();
int StartThreads(int num);
int StopThreads();
void AddTask(Task *);
int GetTaskNum();
int GetThreadNum();
bool CreateTaskManager();
private:
std::list<Thread *> m_ThreadList;
TaskManager *m_pTaskMgr;
}; #endif
ThreadManager.cpp
/*********************
* author: zhanghang
* date: 2016.02.27
* file: ThreadManager.cpp
* usage: this class is to manage the task pool
*************************/ #include <iostream>
#include "ThreadManager.h"
#include "Thread.h"
#include "Task.h"
#include "TaskManager.h" ThreadManager::ThreadManager(): m_pTaskMgr(NULL)
{
std::cout << "ThreadManager::ThreadManager*" << (void *)this << std::endl;
} ThreadManager::~ThreadManager()
{
std::cout << "ThreadManager::~ThreadManager#" << (void *)this << std::endl;
if(m_ThreadList.size() > 0)
{
StopThreads();
} if(NULL != m_pTaskMgr)
{
delete m_pTaskMgr;
m_pTaskMgr = NULL;
}
} bool ThreadManager::CreateTaskManager()
{
if(NULL == m_pTaskMgr)
{
m_pTaskMgr = new TaskManager();
if(NULL == m_pTaskMgr)
{
return false;
}
}
return true;
} // return the truely thread num
int ThreadManager::StartThreads(int num)
{
if(!CreateTaskManager())
{
return 0;
} int result = 0;
for(int i=0; i<num; ++i)
{
Thread *pThread = NULL;
pThread = new Thread(*m_pTaskMgr); result = pThread->Run();
if(0 != result)
{
std::cout << "one thread started failed! error code: " << result << std::endl;
continue;
} m_ThreadList.push_back(pThread);
} return m_ThreadList.size();
} // return the num of threads that left
int ThreadManager::StopThreads()
{
std::list<Thread *>::iterator threadItr = m_ThreadList.begin();
int result = 0;
while(m_ThreadList.end() != threadItr)
{
result = (*threadItr)->Stop(); if(0 != result)
{
std::cout << "one thread stopped failed! error code: " << result << std::endl;
++threadItr;
continue;
} // delete the thread
delete *threadItr;
m_ThreadList.erase(threadItr++);
} // the left thread
return m_ThreadList.size();
} void ThreadManager::AddTask(Task *pTask)
{
if(!CreateTaskManager())
{
return;
} m_pTaskMgr->AddTask(pTask);
} int ThreadManager::GetTaskNum()
{
if(!CreateTaskManager())
{
return 0;
} return m_pTaskMgr->GetTaskNum();
} int ThreadManager::GetThreadNum()
{
return m_ThreadList.size();
}
main.cpp
/*************
* author: zhanghang
* date: 2016.02.27
* file: main.cpp
* usage: this is a demo of taskpool
********************************/ #include "ThreadManager.h"
#include "Task.h"
#include <iostream>
#include <unistd.h> #define THREAD_NUM 3 // this is the task
class MyTask : public Task
{
public:
MyTask()
{
std::cout << "MyTask::MyTask*" << (void *)this << std::endl;
}
~MyTask()
{
std::cout << "MyTask::~MyTask#" << (void *)this << std::endl;
}
void Process()
{
std::cout << "thread id: " << pthread_self() << std::endl;
Delay(1);
}
}; int main(int argc, char **argv)
{
ThreadManager threadMgr;
threadMgr.StartThreads(THREAD_NUM); for(int i=0; i<20; ++i)
{
MyTask *pMyTask = new MyTask();
Task *pTask = (Task *) pMyTask; // add task
threadMgr.AddTask(pTask);
} sleep(4); threadMgr.StopThreads(); return 1;
}
makefile
main: ThreadMgr Thread TaskMgr
g++ -o main main.cpp ThreadManager.o Thread.o TaskManager.o -lpthread -g
ThreadMgr:
g++ -c ThreadManager.cpp ThreadManager.h Thread.h TaskManager.h Task.h -g
Thread:
g++ -c Thread.cpp Thread.h Task.h TaskManager.h -g
TaskMgr:
g++ -c TaskManager.cpp TaskManager.h GuardLock.h Task.h -g clean:
rm *.o
运行程序后程序的输出:
ThreadManager::ThreadManager*0xbfdf52d4
TaskManager::TaskManager*0x8599008
Thread::Thread*0x8599030
Thread::Thread*0x85990f0
Thread::Thread*0x85991b0
MyTask::MyTask*0x8599270
MyTask::MyTask*0x8599290
MyTask::MyTask*0x85992b0
MyTask::MyTask*0x85992d0
MyTask::MyTask*0x85992f0
MyTask::MyTask*0x8599310
MyTask::MyTask*0x8599330
MyTask::MyTask*0x8599350
MyTask::MyTask*0x8599370
MyTask::MyTask*0x8599390
MyTask::MyTask*0x85993b0
MyTask::MyTask*0x85993d0
MyTask::MyTask*0x85993f0
MyTask::MyTask*0x8599410
MyTask::MyTask*0x8599430
MyTask::MyTask*0x8599450
MyTask::MyTask*0x8599470
MyTask::MyTask*0x8599490
MyTask::MyTask*0x85994b0
MyTask::MyTask*0x85994d0
thread id: 3058080576
thread id: 3074865984
thread id: 3066473280
MyTask::~MyTask#0x8599270
thread id: 3058080576
MyTask::~MyTask#0x8599290
thread id: 3074865984
MyTask::~MyTask#0x85992b0
thread id: 3066473280
MyTask::~MyTask#0x85992d0
thread id: 3058080576
MyTask::~MyTask#0x85992f0
thread id: 3074865984
MyTask::~MyTask#0x8599310
thread id: 3066473280
MyTask::~MyTask#0x8599330
thread id: 3058080576
MyTask::~MyTask#0x8599350
thread id: 3074865984
MyTask::~MyTask#0x8599370
thread id: 3066473280
MyTask::~MyTask#0x85993b0
thread id: 3074865984
MyTask::~MyTask#0x8599390
thread id: 3058080576
MyTask::~MyTask#0x85993f0
thread id: 3074865984
MyTask::~MyTask#0x85993d0
thread id: 3066473280
MyTask::~MyTask#0x8599410
thread id: 3058080576
MyTask::~MyTask#0x8599430
thread id: 3074865984
MyTask::~MyTask#0x8599450
thread id: 3066473280
MyTask::~MyTask#0x8599470
thread id: 3058080576
MyTask::~MyTask#0x8599490
MyTask::~MyTask#0x85994b0
MyTask::~MyTask#0x85994d0
Thread::~Thread#0x8599030
Thread::~Thread#0x85990f0
Thread::~Thread#0x85991b0
ThreadManager::~ThreadManager#0xbfdf52d4
TaskManager::~TaskManager#0x8599008
谢谢。
pthread库实现一个简单的任务池的更多相关文章
- 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”
这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...
- C 封装一个简单二叉树基库
引文 今天分享一个喜欢佩服的伟人,应该算人类文明极大突破者.收藏过一张纸币类型如下 那我们继续科普一段关于他的简介 '高斯有些孤傲,但令人惊奇的是,他春风得意地度过了中产阶级的一生,而 没有遭受到冷 ...
- 一个简单、易用的Python命令行(terminal)进度条库
eprogress 是一个简单.易用的基于Python3的命令行(terminal)进度条库,可以自由选择使用单行显示.多行显示进度条或转圈加载方式,也可以混合使用. 示例 单行进度条 多行进度条 圆 ...
- 实现一个简单的Laravel的dd库
前几天写了一个简单的Laravel的dd库. 为什么自己要写一个这样的库? Laravel本身已经实现了自己的输出dd函数,但是我之所以要写这样一个库,一来是因为Laravel本身对这个库的封装没办法 ...
- sopt:一个简单的python最优化库
引言 最近有些朋友总来问我有关遗传算法的东西,我是在大学搞数学建模的时候接触过一些最优化和进化算法方面的东西,以前也写过几篇博客记录过,比如遗传算法的C语言实现(一):以非线性函数求极值为例和 ...
- C 封装一个通用链表 和 一个简单字符串开发库
引言 这里需要分享的是一个 简单字符串库和 链表的基库,代码也许用到特定技巧.有时候回想一下, 如果我读书的时候有人告诉我这些关于C开发的积淀, 那么会走的多直啊.刚参加工作的时候做桌面开发, 服务是 ...
- 极力推荐一个简单好用的C++JSON库
极力推荐一个简单好用的C++JSON库CJsonObject,让使用json如使用C++原生的结构体那般方便,随心所欲.CJsonObject是个优秀的C++JSON库,也许会是你见过的最为简单易 ...
- 一个简单的C共享库的创建及Python调用此库的方法
/********************************************************************* * Author : Samson * Date ...
- htpwdScan — 一个简单的HTTP暴力破解、撞库攻击脚本
李姐姐之前跟我们分享了子域名枚举工具subDomainBrute<subDomainsBrute — 改进渗透测试时暴力枚举子域名的python脚本>,这回带给我们htpwdScan ht ...
随机推荐
- 5 项目---自定义用户模型以及轮播图图片url返回格式
创建自定义的用户模型类 1. 用命令创建users 应用 2. 将users 注册到settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'd ...
- 一‘php文件系统
一.获取文件信息 ——FILE——,获取当前文件的绝对路径,包含文件名, __DIR__等价于dirname(__FILE__),不包含文件名的路径,
- day11 - 15(装饰器、生成器、迭代器、内置函数、推导式)
day11:装饰器(装饰器形成.装饰器作用.@语法糖.原则.固定模式) 装饰器形成:最简单的.有返回值的.有一个参数的.万能参数 函数起的作用:装饰器用于在已经完成的函数前后增加功能 语法糖:使代码变 ...
- php 出现Warning: A non-numeric value encountered问题的原因及解决方法
在使用(+ - * / ** % << >> | & ^) 运算时,例如a+b,如果a是开始一个数字值,但包含非数字字符(123a),b不是数字值开始时(b456),就 ...
- 漏洞复现——tomcat远程代码执行漏洞
漏洞描述: 当存在该漏洞的Tomcat 运行在 Windows 主机上,且启用了 HTTP PUT请求方法,攻击者可通过构造的攻击请求向服务器上传包含任意代码的 JSP 文件,造成任意代码执行 影响范 ...
- centos7 mysql+MHA高可用安装
https://dzone.com/articles/consul-proxysql-and-mysql-ha?utm_medium=feed&utm_source=feedpress.me& ...
- 大数据分析引擎Apache Flink
Apache Flink是一个高效.分布式.基于Java实现的通用大数据分析引擎,它具有分布式 MapReduce一类平台的高效性.灵活性和扩展性以及并行数据库查询优化方案,它支持批量和基于流的数据分 ...
- moment.js 常用(几天前、相差几天、自然周、自然月)
let pickDate = moment(this.searchForm.date); let firstDay = pickDate.day(0).format('YYYYMMDD');//上周天 ...
- mac+php+nginx+laravel配置启动
首先保证mac安装php,nginx,composer 根据laravel中文文档进行安装 http://laravelacademy.org/post/6665.html 直接指向 composer ...
- zabbix3.4.7集成grafana详细步骤
打开官方网站下载grafana并安装 wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.4-1. ...