Linux pthread 线程池实现
基于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 线程池实现的更多相关文章
- linux C 线程池(物不可穷也~)
Linux 多线程编程之 线程池 的原理和一个简单的C实现,提高对多线程编 程的认知,同步处理等操作,以及如何在实际项目中高效的利用多线程开 发. 1. 线程池介绍 为什么需要线程池??? 目前的大 ...
- Linux C++线程池实例
想做一个多线程服务器测试程序,因此参考了github的一些实例,然后自己动手写了类似的代码来加深理解. 目前了解的线程池实现有2种思路: 第一种: 主进程创建一定数量的线程,并将其全部挂起,此时线程状 ...
- Linux C++线程池
.为什么需要线程池? 部分应用程序需要执行很多细小的任务,对于每个任务都创建一个线程来完成,任务完成后销毁线程,而这就会产生一个问题:当执行的任务所需要的时间T1小于等于创建线程时间T2和销毁线程时间 ...
- Linux下线程池的理解与简单实现
首先,线程池是什么?顾名思义,就是把一堆开辟好的线程放在一个池子里统一管理,就是一个线程池. 其次,为什么要用线程池,难道来一个请求给它申请一个线程,请求处理完了释放线程不行么?也行,但是如果创建线程 ...
- Linux简单线程池实现(带源码)
这里给个线程池的实现代码,里面带有个应用小例子,方便学习使用,代码 GCC 编译可用.参照代码看下面介绍的线程池原理跟容易接受,百度云下载链接: http://pan.baidu.com/s/1i3z ...
- C++代码利用pthread线程池与curl批量下载地图瓦片数据
项目需求编写的程序,稳定性有待进一步测试. 适用场景:在网络地图上,比如天地图与谷歌地图,用户用鼠标在地图上拉一个矩形框,希望下载该矩形框内某一层级的瓦片数据,并将所有瓦片拼接成一个完整的,包含地理坐 ...
- 【Linux】线程池
首先,线程池是什么?顾名思义,就是把一堆开辟好的线程放在一个池子里统一管理,就是一个线程池. 其次,为什么要用线程池,难道来一个请求给它申请一个线程,请求处理完了释放线程不行么?也行,但是如果创建线程 ...
- 基于linux与线程池实现文件管理
项目要求 1.基本 用线程池实现一个大文件夹的拷贝,大文件夹嵌套很多小文件:实现复制到指定文件夹的全部文件夹. 2.扩充功能 显示进度条:拷贝耗时统计:类似linux的tree,不能直接用system ...
- linux中线程池【转】
本文转载自:http://blog.csdn.net/yusiguyuan/article/details/18401277 一.线程池 大多数的网络服务器,包括Web服务器都具有一个特点,就是单位时 ...
随机推荐
- JS JavaScript中的this
this是JavaScript语言中的一个关键字 它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用. function test() { this.x = 1; } 上面代码中,函 ...
- Question20171231 聊聊为什么32bit只能支持4GB内存
1. 32位系统最大只能支持4GB内存之由来 也许大家对这个问题都不陌生,实际装过系统用过电脑的朋友可能都有这样的经历:自己电脑配的是4G的内存条,可是装完系统之后发现电脑上显示的只有3.2G左右可用 ...
- 分组函数group by和Oracle中分析函数partition by的用法以及区别
1.分组函数group by和Oracle中分析函数partition by的用法以及区别 2.开窗函数.
- RabbitMQ消息中间件极速入门与实战
1:初识RabbitMQ RabbitMQ是一个开源的消息代理和队列服务器,用来通过普通协议在完全不同的应用之间共享数据,RabbitMQ是使用Erlang语言来编写的,并且RabbitMQ是基于AM ...
- 剑指offer js算法练习(1-10)
1.二维数组中的查找 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数, ...
- Lucene 工作原理
Lucene 简介 Lucene 是一个基于 Java 的全文信息检索工具包,它不是一个完整的搜索应用程序,而是为你的应用程序提供索引和搜索功能.Lucene 目前是 Apache Jakarta 家 ...
- Python3 operator模块关联代替Python2 cmp() 函数
Python2 cmp() 函数 描述 cmp(x,y) 函数用于比较2个对象,如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1. Python ...
- 解决每次运行Xcode,都需要输入密码的问题
新买的Mac,在安装了 Xcode 7.1的时候,不知道是配置信息哪里手残了一下,导致每次运行Xcode模拟器 后 都需要输入一次密码. 为此在网上也是查阅了不少的资料,当时 所谓的 XCode--- ...
- docker 启动 nginx 访问不了的问题
使用版本:nginx version: nginx/1.13.8 正使用docker启动nginx容器的时候,一切都很正常,容器也起来了 docker run -dit -p 80:80 --name ...
- Vue报错 [Vue warn]: Cannot find element
在前端开发全面进入前端的时代 作为一个合格的前端开发工作者 框架是不可或缺的Vue React Anguar 作为前端小白,追随大佬的脚步来到来到博客园,更新现在正在学习的Vue 注 : 相信学习Vu ...