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服务器都具有一个特点,就是单位时 ...
随机推荐
- android 界面控件 textview 全解
textview基本使用: <TextView 10. android:id="@+id/txtOne" 11. android:layout_width="200 ...
- ORACLE 账户解除锁定
用pl/sql连接数据库发现账户被锁定.本以为管理员账户才能解锁.同其他账户登录也能解锁 pl/sql下执行命令 alter user **** account unlock ***处为待解锁的 ...
- CALayer创建图层(转)
一.添加一个图层 添加图层的步骤: 1.创建layer 2.设置layer的属性(设置了颜色,bounds才能显示出来) 3.将layer添加到界面上(控制器view的layer上) @int ...
- flex布局——回顾
flex 即为弹性布局. 任何一个容器都可以指定为flex布局. .box{display:flex} 行内元素可以使用flex布局 .box{display: inline-flex} webkit ...
- LeetCode-环形链表II
LeetCode-环形链表II 为找到入口点可以用以下方法 使用快慢指针法直到两个指针相遇 头节点处创建一个新的指针,并且向前移动,两个指针相遇处创建一个新的指针,并且向前移动,直到两个指针相遇为入口 ...
- 服务命令只支持基本的LSB操作(启动、停止、重新启动、尝试重启、重新加载、强制重新加载、状态)。对于其他操作,请尝试使用systemctl。
The service command supports only basic LSB actions (start, stop, restart, try-restart, reload, forc ...
- javascript--淘宝页面的放大镜效果
放大镜效果需求: 鼠标放入原图中,会出现一个黄色的遮盖层和一个放大的图片,鼠标移动时候,遮盖层会跟着鼠标一起移动,同时放大的图片会跟着一起移动. 实现过程: 1.鼠标移入,遮盖层和大图片显示 2.鼠标 ...
- MySQL索引介绍
引言 今天Qi号与大家分享什么是索引.其实索引:索引就相当于书的目录 索引介绍 用官方的话说就是 索引是为了加速对表中数据行的检索而创建的一种分散的存储结构.索引是针对表而建立的,它是由数据页面以外的 ...
- Volatile的详解
volatile关键字修饰的共享变量主要有两个特点:1.保证了不同线程访问的内存可见性 2.禁止重排序 在说内存可见性和有序性之前,我们有必要看一下Java的内存模型(注意和JVM内存模型的区分 ...
- 怎么修复网站漏洞 骑士cms的漏洞修复方案
骑士CMS是国内公司开发的一套开源人才网站系统,使用PHP语言开发以及mysql数据库的架构,2019年1月份被某安全组织检测出漏洞,目前最新版本4.2存在高危网站漏洞,通杀SQL注入漏洞,利用该网站 ...