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服务器都具有一个特点,就是单位时 ...
随机推荐
- SQLite动态库下载
其中带有“bundle”字样的表示动态库是按混合模式编译的,在 使用的时候只需要System.Data.SQLite.dll就可以了 而不带“bundle”的则是将非托管部分和托管部分分别编 译,Sy ...
- android中的键值对
hashmap,contentvalue,namevaluepair,jsonobject ArrayList和HashMap的区别:内部元素:ArrayList储存的是单个对象(此对象是可以通过设置 ...
- Angularjs基础(三)
AngularJS ng-model 指令 ng-model 指令用于绑定应用程序数据到HTML 控制器(input,select,textarea)的值ng-model指令 ng-model指令可以 ...
- PostgreSQL数据库的安装
1 总体规划 操作系统 CentOS Linux release 7.5.1804 处理器 1 内存 4G 硬盘 38G 主机名称 chenzx IP地址 192.168.56.8 1.1 用户组和用 ...
- MySQL-5.7.20主从复制测试[20180110]
前言 MySQL 5.7.20测试主从复制 环境 主库 192.168.1.59 t-xi-sonar01 从库 192.168.1.51 t-xi-orc01 设 ...
- Lintcode算法
题目: 给出一组非负整数,重新排列他们的顺序把他们组成一个最大的整数. 样例 给出 [1, 20, 23, 4, 8],返回组合最大的整数应为8423201. 思路:直接交换两个数,然后判断交换之后的 ...
- Linux系统修改/etc/sysconfig/i18n文件,桌面无法正常显示
在Windows环境下使用SSH Secure Shell Client登陆VMware Workstation中Linux系统查询hive表时,中文显示乱码:数字和url显示为NULL,网上说: 1 ...
- js根据年份获取某月份有几天
function getNum(year, month) { var temp; month = parseInt(month, 10); temp = new Date(year, month, 0 ...
- (转)手游应该怎么做 UI 设计?
之前一直做互动设计,在UI上有一些积累. 转战手游后发现,有着标准.互动方式.用户行为等等与常规大屏UI设计的不同,但是在设计流程,思考方式上是一样的. 以目前项目中一个界面为例(未完成版本)来说一下 ...
- Java处理中文乱码问题
package servlet; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.ser ...