线程池采用了预创建技术,提前创建好一定数量的线程,有新的任务到来时直接处理对应的任务。
线程池主要包括了三部分:
任务队列、工作线程、管理者线程
(1)通过线程池提供的API函数,将一个待处理的任务添加到任务队列,或者从任务队列中删除;
(2)已处理的任务将被删除;
(3)线程池的使用者,也就是调用线程池函数往任务队列中添加任务的线程就是生产者线程。
(1)线程池维护了一定数量的工作线程,它们的作用是不断的读取任务队列,从里边取出任务并处理;
(2)如果任务队列为空,工作线程将会被阻塞(使用条件变量或信号量阻塞);
(3)如果阻塞之后有了新的任务,由生产者将阻塞解除,工作线程开始工作;
(1)它的任务是周期性的对任务队列中的任务数量以及处于忙状态的工作线程个数进行检测;
(2)当任务过多的时候,可以适当的创建一些新的工作线程;
(3)当任务过少的时候,可以适当的销毁一些工作线程;
大致过程如下:
(1)降低资源消耗。通过重复利用已创建好的线程来降低线程创建和销毁时给系统带来的消耗。
(2)提高响应速度。当任务到达时,任务可以不需要等待线程创建就能立即得到处理。
(3)提高线程的可管理性。我们可以对线程池里的线程进行统一的分配,调优和监控。
问题:创建的线程越多性能越高,对吗?
答:不对。线程数量越多,可能会导致线程切换越频繁, 进而还有可能导致程序运行效率降低。多线程程序的运行效率, 呈现为正态分布, 线程数量从最开始的1开始逐渐增加, 程序的运行效率也逐渐变高, 直到线程数量达到一个临界值, 然后再次增加线程数量时, 程序的运行效率会减小(主要是由于频繁地线程切换影响到了整体线程运行效率)。
线程池的成员变量:
threadpool:threadpool.cc
g++ $^ -o $@ -lpthread
clean:
rm -f threadpool
#pragma once
#include
#include
using namespace std;
class Task
{
private:
int x;int y;
char op;
public:
Task(int _x,int _y,char _op)
:x(_x)
,y(_y)
,op(_op){ }
Task()
{};
void Run()
{
int ret=0;
switch(op){
case '+':
ret=x+y;
break;
case '-':
ret=x-y;
break;
case '*':
ret=x*y;
break;
case '/':
ret=x/y;
break;
case '%':
ret=x%y;
break;
}
printf("%d %c %d = %d\n",x,op,y,ret);
}
};
#pragma once
#include
#include
#include
#include
using namespace std;
#define NUM 4
template
class ThreadPool
{
private:
queue q;//任务队列
int thread_num;//线程池的线程数量
pthread_mutex_t lock;//互斥锁
pthread_cond_t cond;//条件变量
public:
ThreadPool(int num=NUM)//初始化变量
:thread_num(num){
pthread_mutex_init(&lock,NULL);
pthread_cond_init(&cond,NULL);
}
bool Empty()
{
return q.size()==0?true:false;
}
static void* Routine(void* arg)//线程执行流
{
pthread_detach(pthread_self());//线程分离
ThreadPool* self=(ThreadPool*)arg;
while(1)
{
self->LockQueue();
while(self->Empty())//任务队列是否为空
{
self->Wait();
}
T data;
self->Pop(data);//取出任务
self->UnlockQueue();
cout<
#include"threadpool.hpp"
#include"Task.hpp"
#include
#include
int main()
{
ThreadPool<Task> * q=new ThreadPool<Task>();//创建线程池
q->ThreadPoolInit();
srand((long int)time(NULL));
while(1) //主线程往任务队列中放任务
{
char arr[]="+-*/%";
int x=rand()%100+1;
int y=rand()%100+1;
char op=arr[rand()%5];
Task t(x,y,op);//创建任务
q->Push(t);//将任务推送给队列中
}
return 0;
}
运行结果: