池是一组资源的集合,这组资源在服务器启动之初就被完全创建好并初始化。通俗来说,池是资源的容器,本质上是对资源的复用。
流程:
- 创建线程池
- 添加任务:
a. 加锁保护线程任务队列
b. 添加任务结构体到任务队列
c. 解锁
d. 条件变量唤醒线程 - 删除线程池
基本线程池代码:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
typedef struct work{
void * (*process)(void * arg);
void * args;
struct work * next;
}worker;
typedef struct{
pthread_mutex_t pool_lock;
pthread_cond_t cond;
worker * queuehead;
int cur_queue_cont;
pthread_t * pthread_num; //数组;
int max_thread;
int shutdown;
}pool;
pool *mypool;
//线程体函数
void * thread_routine(void *args)
{
pthread_t *tid = (pthread_t *)args;
printf("start thread id = %ld.\n",*tid);
while(1){
//上锁
pthread_mutex_lock(&mypool->pool_lock);
//当无任务并且不退出时进入阻塞
if(mypool->cur_queue_cont == 0 && !mypool->shutdown){
//阻塞等待任务
pthread_cond_wait(&mypool->cond,&mypool->pool_lock);
}
//线程退出
if(mypool->shutdown){
pthread_mutex_unlock(&mypool->pool_lock);
pthread_exit(NULL); //线程退出
}
//等待任务
mypool->cur_queue_cont --;
//从队列头拿出一个任务
worker * work = mypool->queuehead;
mypool->queuehead = work->next;
//临界操作完成,解锁,开始完成任务
pthread_mutex_unlock(&mypool->pool_lock);
//运行任务
work->process((void *)work->args);
}
}
//工作任务
void * invok_process(void * arg)
{
sleep(2);
printf("this is thread invok %d affair.\n",*(int *)arg);
}
//创建线程池
//num:线程数
void create_poll(int num)
{
int i,ret;
//分配内存
mypool = (pool *)malloc(sizeof(*mypool));
if(mypool == NULL){
printf("malloc pool memory is fail.\n");
return ;
}
pthread_mutex_init(&mypool->pool_lock,NULL);
pthread_cond_init(&mypool->cond,NULL);
mypool->queuehead = NULL;
mypool->shutdown = 0; //线程不退出
mypool->max_thread = num;
//分配保存线程号的内存
mypool->pthread_num = (pthread_t *)malloc(num*sizeof(pthread_t));
for(i=0; i<num; i++)
{
ret = pthread_create(&(mypool->pthread_num[i]),NULL,thread_routine,(void *)&(mypool->pthread_num[i]));
if(ret != 0)
{
printf("create thread is fail.\n");
}
}
}
//添加任务到工作队列
void add_work(void * (*process)(void *),void *args)
{
//分配任务结构体内存
worker *work = (worker *)malloc(sizeof(worker));
work->process = process; //任务函数
work->args = args; //传递参数
work->next = NULL;
pthread_mutex_lock(&mypool->pool_lock); //临界资源上锁(保护线程池结构体)
worker * pwork = mypool->queuehead; //把任务结构体添加到等待队列尾
if(pwork != NULL){、
while(pwork->next != NULL)
pwork = pwork->next;
pwork->next = work;
}else{
mypool->queuehead = work;
}
mypool->cur_queue_cont ++;
pthread_mutex_unlock(&mypool->pool_lock); //解锁
pthread_cond_signal(&mypool->cond); //发送一个信号供线程池线程抢占运行
}
//删除线程池
void destory_pool()
{
int i;
mypool->shutdown = 1;
pthread_cond_broadcast(&mypool->cond);
for(i=0; i<mypool->max_thread; i++){
pthread_join(mypool->pthread_num[i],NULL);
}
free(mypool->pthread_num);
worker * tmp;
while(mypool->queuehead){
tmp = mypool->queuehead;
mypool->queuehead = mypool->queuehead->next;
free(tmp);
}
pthread_mutex_destroy(&mypool->pool_lock);
pthread_cond_destroy(&mypool->cond);
}
int main(int argc, const char *argv[])
{
int i,num[10];
//create thread poll
create_poll(5); //创建线程池
sleep(2);
//add work
for(i=0; i<10; i++){
num[i] = i;
add_work(invok_process,(void *)&num[i]);
}
sleep(3);
//destory
destory_pool(); // 删除线程池
free(mypool); //删除线程池结构体
printf("free resource is ok.\n");
return 0;
}