基于pthread封装了一个简易的ThreadPool,具有以下特性:

  1.具有优先级的任务队列

  2.线程池大小可以二次调整,增加线程或者删除空闲线程

  3.任务两种重写方式,重写run或者使用函数回调

首先是任务类的声明

class Task{
public:
string taskName; public:
Task(){}
Task(string _taskName):taskName(_taskName){
priority=;
}
void setPriority(int pri){
priority=pri;
}
int getPriority(){
return priority;
} virtual ~Task(){} virtual void run()=;
public:
int priority;
};
struct TaskCom{
bool operator()(const Task* t1,const Task* t2){
return t1->priority<t2->priority;
}
};
class CbTask:public Task{//回调版本的task
public:
CbTask(string name,int pri):Task(name){
setPriority(pri);
}
void setCallBack(void *(*_process) (void *_arg), void *_arg){
process=_process;
arg=_arg;
}
void run(){
(*process) (arg);
}
private:
void*(*process)(void *arg);
void *arg;
};
class MyTask1:public Task{
public:
MyTask1(string name,int pri):Task(name){
setPriority(pri);
}
void run(){
printf("hello,this is MyTask1\n");
sleep();
}
};
MyTask1 *task1=new MyTask1("mytask1",); void *printStr(void * str){
printf("%s\n",str);
}
CbTask *task6=new CbTask("mytask6",);
char *str="你好";
task6->setCallBack(printStr,static_cast<void*>(str));

线程池声明

class ThreadPool{
private:
static priority_queue<Task*,vector<Task*>,TaskCom > taskList;//带优先级
static map<pthread_t,int> threads;
bool shutdown;
int maxThreadNum;
int ThreadNum; static pthread_mutex_t mutex;
static pthread_mutex_t map_mutex;
static pthread_cond_t cond; protected:
static void *threadRoutine(void *arg);
static void setThreadStat(pthread_t tid,int stat);
public:
void poolInit();
void poolDestroy();
void addThread();
void delThread(int n);
void addTask(Task *task);
int getTaskListSize();
int getPoolSize(); ThreadPool(int _threadNum);
~ThreadPool();
enum ThreadStat{
THREAD_RUN=,
THREAD_WAIT,
THREAD_SHUT
};

线程池实现

#include "ThreadPool.h"

priority_queue<Task*,vector<Task*>,TaskCom> ThreadPool::taskList;
map<pthread_t,int> ThreadPool::threads; pthread_mutex_t ThreadPool::mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t ThreadPool::map_mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t ThreadPool::cond=PTHREAD_COND_INITIALIZER; ThreadPool::ThreadPool(int _threadNum):maxThreadNum(_threadNum){
poolInit();
}
ThreadPool::~ThreadPool(){
poolDestroy();
}
void *ThreadPool::threadRoutine(void *arg){
pthread_t tid=pthread_self();
pthread_mutex_lock(&map_mutex);
threads.insert(make_pair(tid,THREAD_WAIT));
int &threadStat=threads[tid];
pthread_mutex_unlock(&map_mutex);
while(){
pthread_mutex_lock(&mutex);
while(taskList.size()==&&threadStat==THREAD_WAIT){
pthread_cond_wait(&cond,&mutex);
}
if(threadStat==THREAD_SHUT){
pthread_mutex_unlock(&mutex);
printf("thread %lu will exit\n",tid);
pthread_exit(NULL);
}
// printf("task num=%d\n",taskList.size());
Task *task=taskList.top();
taskList.pop();
// printf("task num=%d\n",taskList.size());
setThreadStat(tid,THREAD_RUN);
printf("thread %lu is running with task--> %s*** %d\n",tid,task->taskName.c_str(),task->getPriority());
pthread_mutex_unlock(&mutex); task->run();
setThreadStat(tid,THREAD_WAIT); printf("thread %lu has done with task--> %s\n",tid,task->taskName.c_str()); }
return NULL;
}
void ThreadPool::setThreadStat(pthread_t tid,int stat){
threads[tid]=stat;
}
void ThreadPool::addThread(){
pthread_t tid;
pthread_create(&tid,NULL,threadRoutine,NULL);
ThreadNum++;
} void ThreadPool::delThread(int n){
int num=;
int size=getPoolSize();
if(n>size){
printf("pool size is less than you input\n");
return;
}
while(num<n){
for(map<pthread_t,int>::iterator ite=threads.begin();ite!=threads.end();){
if(ite->second==THREAD_WAIT){
setThreadStat(ite->first,THREAD_SHUT);
// printf("**thread %lu \n",ite->first);
pthread_cond_broadcast(&cond);
pthread_join(ite->first,NULL);
map<pthread_t,int>::iterator tmp=++ite;
pthread_mutex_lock(&map_mutex);
threads.erase(--ite);
ThreadNum--;
if(ThreadNum!=threads.size())
printf("thread num is wrong\n");
pthread_mutex_unlock(&map_mutex);
ite=tmp;
// printf("**thread %lu \n",ite->first);
// printf("**thread %d\n",threads.size());
num++;
if(num==n)
break;
}else{
++ite;
}
} }
}
void ThreadPool::poolInit(){
for(int i=;i<maxThreadNum;i++)
addThread();
}
void ThreadPool::poolDestroy(){
printf("thread pool begin to destory\n");
while(threads.size()!=){
for(map<pthread_t,int>::iterator ite=threads.begin();ite!=threads.end();){
if(ite->second==THREAD_WAIT){
setThreadStat(ite->first,THREAD_SHUT);
pthread_cond_broadcast(&cond);
pthread_join(ite->first,NULL);
map<pthread_t,int>::iterator tmp=++ite;
pthread_mutex_lock(&map_mutex);
threads.erase(--ite);
ThreadNum--;
if(ThreadNum!=threads.size())
printf("thread num is wrong\n");
pthread_mutex_unlock(&map_mutex);
ite=tmp;
}
}
}
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
printf("thread pool has destoryed\n");
}
void ThreadPool::addTask(Task *task){
taskList.push(task);
pthread_cond_signal(&cond);
}
int ThreadPool::getTaskListSize(){
return taskList.size();
}
int ThreadPool::getPoolSize(){
return ThreadNum;
}

工程

https://github.com/tla001/ThreadPool

Linux pthread 线程池实现的更多相关文章

  1. linux C 线程池(物不可穷也~)

    Linux 多线程编程之 线程池 的原理和一个简单的C实现,提高对多线程编 程的认知,同步处理等操作,以及如何在实际项目中高效的利用多线程开 发. 1.  线程池介绍 为什么需要线程池??? 目前的大 ...

  2. Linux C++线程池实例

    想做一个多线程服务器测试程序,因此参考了github的一些实例,然后自己动手写了类似的代码来加深理解. 目前了解的线程池实现有2种思路: 第一种: 主进程创建一定数量的线程,并将其全部挂起,此时线程状 ...

  3. Linux C++线程池

    .为什么需要线程池? 部分应用程序需要执行很多细小的任务,对于每个任务都创建一个线程来完成,任务完成后销毁线程,而这就会产生一个问题:当执行的任务所需要的时间T1小于等于创建线程时间T2和销毁线程时间 ...

  4. Linux下线程池的理解与简单实现

    首先,线程池是什么?顾名思义,就是把一堆开辟好的线程放在一个池子里统一管理,就是一个线程池. 其次,为什么要用线程池,难道来一个请求给它申请一个线程,请求处理完了释放线程不行么?也行,但是如果创建线程 ...

  5. Linux简单线程池实现(带源码)

    这里给个线程池的实现代码,里面带有个应用小例子,方便学习使用,代码 GCC 编译可用.参照代码看下面介绍的线程池原理跟容易接受,百度云下载链接: http://pan.baidu.com/s/1i3z ...

  6. C++代码利用pthread线程池与curl批量下载地图瓦片数据

    项目需求编写的程序,稳定性有待进一步测试. 适用场景:在网络地图上,比如天地图与谷歌地图,用户用鼠标在地图上拉一个矩形框,希望下载该矩形框内某一层级的瓦片数据,并将所有瓦片拼接成一个完整的,包含地理坐 ...

  7. 【Linux】线程池

    首先,线程池是什么?顾名思义,就是把一堆开辟好的线程放在一个池子里统一管理,就是一个线程池. 其次,为什么要用线程池,难道来一个请求给它申请一个线程,请求处理完了释放线程不行么?也行,但是如果创建线程 ...

  8. 基于linux与线程池实现文件管理

    项目要求 1.基本 用线程池实现一个大文件夹的拷贝,大文件夹嵌套很多小文件:实现复制到指定文件夹的全部文件夹. 2.扩充功能 显示进度条:拷贝耗时统计:类似linux的tree,不能直接用system ...

  9. linux中线程池【转】

    本文转载自:http://blog.csdn.net/yusiguyuan/article/details/18401277 一.线程池 大多数的网络服务器,包括Web服务器都具有一个特点,就是单位时 ...

随机推荐

  1. linux 使用sqlite3

    :c中使用sqlite3需要调用函数接口操作: sqlite3 *db; int status=sqlite_open("dbname",&db);//打开或者创建数据库 ...

  2. xcode运行时候 You don’t have permission.

    xcode 不能运行,提示没有权限    是因为使用第三方框架有plist文件存在

  3. D - 湫湫系列故事——减肥记II

    虽然制定了减肥食谱,但是湫湫显然克制不住吃货的本能,根本没有按照食谱行动! 于是,结果显而易见… 但是没有什么能难倒高智商美女湫湫的,她决定另寻对策——吃没关系,咱吃进去再运动运动消耗掉不就好了? 湫 ...

  4. 详解Linux运维工程师

    运维工程师是从一个呆逼进化为苦逼再成长为牛逼的过程,前提在于你要能忍能干能拼,还要具有敏锐的嗅觉感知前方潮流变化.如:今年大数据,人工智能比较火……(相对表示就是 Python 比较火) 之前写过运维 ...

  5. centos7中vsftp的搭建

    开启vsftpd:service vsftpd start关闭vsftp:service vsftpd stop 安装vsftpd: yum -y install vsftpd 建立vsftpd帐号: ...

  6. Java OOP——第三章 多态

    1.多态:(polymorphism): 是具有表现多种形态能力的特征: (专业化的说法:)同一个实现接口(引用类型),使用不同的实例而执行不同的操作 指一个引用(类型)在不同情况下的多种状态.也可以 ...

  7. 【c学习-10】

    #include #include #define SOURCE 0 //递归函数 /* [基本类型 [整型(int,[长整型(long int), [短整型(short int),长度整型(long ...

  8. jquery和vue分别对input输入框手机号码格式化(344)

    jQuery function fomatterTel(val, old) {//val: 当前input的值,old: input上次的值 var str = ""; var t ...

  9. node 写api几个简单的问题

    最近出了一直在做无聊的管理后台,还抽空做了我公司的计费终端,前端vue,后端node,代码层面没啥太多的东西.由于自己node版本是8.0.0,node自身是不支持import和export的,要想基 ...

  10. PHP+AJAX开发幸运大转盘抽奖

    PHP+AJAX开发幸运大转盘抽奖,通过奖品库存.中奖次数来计算中奖概率 奖品设置 $prizes = array( 0 => array( "id" => 0, // ...