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 ...
随机推荐
- Fiddler抓包配置具体步骤
如何查看手机连接的无线wifi的IP? 打开手机,选择设置->进入设置页面选择WLAN->进入WLAN管理,点击手机已经连接的路由器->点击进入查看,即可看见IP地址 如何查看自己电 ...
- pytorch变量
下文中所使用的pytorch版本为1.0.1 在python,如果全局变量在函数中没有提前用global申明,就修改其值,结果是这个全局变量不会被修改,会在这个函数中另外产生一个局部变量(名字相同). ...
- unitest 测试集 实例
-->baidy.py #coding=utf-8from selenium import webdriverfrom selenium.webdriver.common.by import B ...
- 『流畅的Python』第10章笔记_序列类型
一.基础知识 “__”前缀:私有属性.方法,在__dict__中存储时被改写为“_类名__”前缀 “_”前缀:是约定俗成的保护属性.方法,不过编译器不会对之采取任何处理 二.class特殊方法介绍 在 ...
- leetcode-algorithms-18 4Sum
leetcode-algorithms-18 4Sum Given an array nums of n integers and an integer target, are there eleme ...
- Jsop的原理
Jsop的原理:利用script不存在跨域的问题,动态创建script标签,把需要请求的数据源地址赋值给其src属性,并且指定一个回调函数,从而接受到我们想要的数据
- const 内联 枚举 宏
const 常量 程序运行时在常量表中,系统为它分配内存,在堆栈分配了空间:const常量有数据类型:语句末有分号:有类型检查:可以限制范围 //将所有不希望改变的变量加const修饰 const ...
- iOS的Cookie存取
当前一些公司为了快速出一款app,很多时候采用UINavigationController+WebView或者NavigationController+UITabbarVC+WebView的方式,这样 ...
- weblogic补丁安装失败(Patch B25A is mutually exclusive and cannot coexist with patch(es): UIAL)
由于曝出漏洞(CVE-2017-3248)需要将weblogic补丁更新至B25A,但是出现报错.如下: Conflict(s) detected - resolve conflict conditi ...
- mac+php+nginx+laravel配置启动
首先保证mac安装php,nginx,composer 根据laravel中文文档进行安装 http://laravelacademy.org/post/6665.html 直接指向 composer ...