线程池
我们可以创建一个进程池(线程池),预先放一些进程(线程)进去,要用的时候就直接调用,用完之后再把进程归还给进程池,省下创建删除进程的时间,不过当然就需要额外的开销了。
利用线程池与进程池可以使管理进程与线程的工作交给系统管理,不需要程序员对里面的线程、进程进行管理。
线程池主要用于
1、需要大量的线程来完成任务,且完成任务的时间比较短。 WEB服务器完成网页请求这样的任务,使用线程池技术是非常合适的。因为单个任务小,而任务数量巨大,你可以想象一个热门网站的点击次数。但对于长时间的任务,比如一个Telnet连接请求,线程池的优点就不明显了。因为Telnet会话时间比线程的创建时间大多了。
2、对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。
3、接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。突发性大量客户请求,在没有线程池情况下,将产生大量线程,虽然理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,并出现"OutOfMemory"的错误。
线程池优点
首先说一下多线程的好处:多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#include <stack>
#include <queue>
#include <iostream>
using namespace std;
//任务类
class CTASK
{
public:
CTASK(int i);
//~CTASK();
void run()
{
cout << "do task:" <<this->count<< endl;
}
int count;
private:
};
CTASK::CTASK(int i)
{
this->count = i;
}
typedef struct thread_pool
{
pthread_mutex_t mutex;
pthread_cond_t cond;
int idel;//空闲线程
queue<CTASK*> s_stack;//任务队列
}THREAD_POOL;
void* start_routine (void*arg)
{
//创建新的线程的目的是啥? 1.有任务就执行任务 2.没任务就等待
THREAD_POOL* pool = (THREAD_POOL*)arg;
while(1)
{
pthread_mutex_lock(&pool->mutex);
pool->idel++;
if (pool->s_stack.empty())//如果为空就等待
{
cout << "wait for ..." << pthread_self() << endl;
pthread_cond_wait(&pool->cond, &pool->mutex);
cout << "wake up ..." << pthread_self() << endl;
}
//执行任务
pool->idel--;
CTASK* t = pool->s_stack.front();
pool->s_stack.pop();
t->run();
pthread_mutex_unlock(&pool->mutex);
}
}
void thread_pool_init(THREAD_POOL* pool,int count)
{
pthread_mutex_init(&pool->mutex,NULL);
pthread_cond_init(&pool->cond,NULL);
pool->idel = 0;
for (int i=0;i<count;i++)
{
pthread_t pid;
pthread_create(&pid, NULL, start_routine, pool);
pool->idel++;
}
}
void thread_pool_add_task(THREAD_POOL *pool, CTASK *task)
{
//往线程池的结构体队列添加任务
pthread_mutex_lock(&pool->mutex);
pool->s_stack.push(task);
//判断是否有空闲线程 有就出发 没有就创建
if (pool->idel>0)
{
pthread_cond_signal(&pool->cond);
}
else
{
//创建3个线程
//for (int i = 0; i < 3; i++)
//{
pthread_t pid;
pthread_create(&pid, NULL, start_routine, pool);
//}
}
pthread_mutex_unlock(&pool->mutex);
}
int main()
{
THREAD_POOL pool;
thread_pool_init(&pool,3);
for (int i=0;i<10;i++)
{
CTASK* task = new CTASK(i);
thread_pool_add_task(&pool, task);
sleep(1);
}
while (1)
{
sleep(1);
}
return 0;
}