1.线程池:
线程池: 一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着 监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利 用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。
2.C++实现简单的线程池实现计算任务
实现简单逻辑图:
线程池实现ThreadPool.h:
#pragma once
#include<iostream>
#include<pthread.h>
#include<queue>
#define NUM 5
template<typename Task>
class ThreadPool
{
private:
std::queue<Task> _task_queue;//临界资源
pthread_mutex_t _lock;
int _thread_num;
pthread_cond_t _cond;
public:
ThreadPool(int Num=NUM):_thread_num(Num){
pthread_mutex_init(&_lock,nullptr);
pthread_cond_init(&_cond,nullptr);
}
bool IsEmpty(){return _task_queue.empty();}
static void*Routine(void*arg)//静态函数无隐含的this指针
{
pthread_detach(pthread_self());
ThreadPool<Task>*self=(ThreadPool<Task>*)arg;
while(true)
{
pthread_mutex_lock(&(self->_lock));
while(self->IsEmpty())//循环检测临界资源是否就绪
{
//休眠
pthread_cond_wait(&(self->_cond),&(self->_lock));
}
//任务队列有任务
Task t;
self->Pop(t);
pthread_mutex_unlock(&(self->_lock));
//解锁后处理任务
t.Run();
}
}
void Push(const Task&in)//外部添加任务
{
pthread_mutex_lock(&_lock);
_task_queue.push(in);
//唤醒一个线程
pthread_cond_signal(&_cond);
pthread_mutex_unlock(&_lock);
}
void Pop(Task&out)//线程获取任务
{
out=_task_queue.front();
_task_queue.pop();
}
~ThreadPool(){
pthread_mutex_destroy(&_lock);
pthread_cond_destroy(&_cond);
}
void InitThreadPool()
{
pthread_t tid;
for(int i=0;i<_thread_num;i++)
{
pthread_create(&tid,nullptr,Routine,this);//为了避免传参时C++传this指针,在线程执行方法上带static。传参数时将this指针传到线程执行方法上。
}
}
};
需要注意:线程处理函数要用静态成员函数。
因为:在线程处理函数中函数类型一定是void*(void*),如果是成员函数的话自带this指针,函数类型就发生了改变,要用静态成员函数无this指针,为了让线程处理函数能够访问到其他非静态成员函数,pthread_create函数的第四个参数将this指针传给线程处理函数上。
对于线程如何进行任务处理,只要任务类中自己定义了任务处理方法,在这里只要调用成员函数Run即可。
任务处理类,包含任务处理方法Run:Tesk.h
#include<map>
#include<functional>
#include<pthread.h>
class Task
{
private:
int x;int y;char op;
public:
Task()=default;
Task(int _x,int _y,char _op):x(_x),y(_y),op(_op){}
void Run()//计算任务处理方法
{
std::map<char,std::function<int(int,int)>>opMap=
{
{'+',[](int x,int y){return x+y;}},
{'-',[](int x,int y){return x-y;}},
{'*',[](int x,int y){return x*y;}},
{'/',[](int x,int y){return x/y;}},
{'%',[](int x,int y){return x%y;}}
};
double ret=(double)opMap[op](x,y);
std::cout<<"Thread: ["<<pthread_self()<<"]: "<<x<<op<<y<<" "<<ret<<std::endl;
}
};
主函数:
#include"Tesk.h"
#include"ThreadPool.h"
#include<ctime>
#include<cstdlib>
#include<unistd.h>
void TestPool()
{
ThreadPool<Task>*t=new ThreadPool<Task>;
t->InitThreadPool();
srand((unsigned int)time(nullptr));
const char*str="+-*/%";
while(true)
{
int x=rand()%100+1;int y=rand()%100+1;
Task task(x,y,str[rand()%5]);
t->Push(task);
sleep(1);
}
}
int main()
{
TestPool();
return 0;
}
运行结果: