目录
线程池描述结构体
struct threadpool_t {
pthread_mutex_t lock; /* 用于锁住本结构体 */
pthread_mutex_t thread_counter; /* 记录忙状态线程个数的琐 -- busy_thr_num */
pthread_cond_t queue_not_full; /* 当任务队列满时,添加任务的线程阻塞,等待此条件变量 */
pthread_cond_t queue_not_empty; /* 任务队列里不为空时,通知等待任务的线程 */
pthread_t *threads; /* 存放线程池中每个线程的tid。数组 */
pthread_t adjust_tid; /* 存管理线程tid */
threadpool_task_t *task_queue; /* 任务队列(数组首地址) */
int min_thr_num; /* 线程池最小线程数 */
int max_thr_num; /* 线程池最大线程数 */
int live_thr_num; /* 当前存活线程个数 */
int busy_thr_num; /* 忙状态线程个数 */
int wait_exit_thr_num; /* 要销毁的线程个数 */
int queue_front; /* task_queue队头下标 */
int queue_rear; /* task_queue队尾下标 */
int queue_size; /* task_queue队中实际任务数 */
int queue_max_size; /* task_queue队列可容纳任务数上限 */
int shutdown; /* 标志位,线程池使用状态,true或false */
};
线程池任务队列结构体
typedef struct{
void *(*function)(void *); //函数指针,回调函数
void *arg; //上面函数的参数
}threadpool_task_t; //各子线程任务结构体
主函数main
int main(int argv, char *argc[]){
threadpool_t *thp = threadpool_create(3,100,100); //创建线程池,池里最小3个线程,最大100,任务队列最大100
printf("pool inited");
int num[20], i;
for(i = 0; i < 20; i++){
num[i] = i;
printf("add task %d\n", i);
/*int threadpool_add(threadpool_t *pool, void*(*function)(void *arg), void *arg)*/
//向线程池添加任务
threadpool_add(thp, process, (void *)&num[i]);
}
sleep(10);
//等子线程完成任务
threadpool_destroy(thp);
return 0;
}
threadpool_create函数
threadpool_t threasdpool_create(int min_thr_num, int max_thr_num, int queue_max_size){
int i;
threadpool_t *pool = NULL; /*线程池 结构体*/
do{
if((pool = (threadpool_t *)malloc(sizeof(threadpool_t))) == NULL){
printf("malloc threadpool fail");
break;
}
pool->min_thr_num = min_thr_num;
pool->max_thr_num = max_thr_num;
pool->busy_thr_num = 0;
pool->live_thr_num = min_thr_num; //活着的线程数 初值 = 最小线程数
pool->wait_exit_thr_num = 0;
pool->queue_size = 0; //有0个产品
pool->queue_max_size = queue_max_size; //最大任务队列数
pool->queue_front = 0; //队头
pool->queue_rear = 0; //队尾
pool->shutdown = false; //不关闭线程池
/*根据最大线程上限数,给工作线程数组开辟空间,并清零*/
pool->threads = (pthread_t *)malloc(sizeof(pthread_t)*max_thr_num);
if(pool->threads == NULL){
printf("malloc threads fail");
break;
}
memset(pool->threads, 0, sizeof(pthread_t)*max_thr_num);
/*给 任务队列 开辟空间 */
pool->task_queue=(threadpool_task_t*)malloc(sizeof(threadpool_task_t)*queue_max_size);
if(pool->task_queue == NULL){
printf("malloc task_queue fail");
break;
}
/*初始化互斥锁、条件变量*/
if(pthread_mutex_init(&(pool->lock), NULL)!=0
|| pthread_mutex_init(&(pool->thread_counter), NULL)!=0
|| pthread_cond_init(&(pool->queue_not_empty), NULL)!=0
|| pthread_cond_init(&(pool->queue_not_full), NULL)!=0){
printf("init the lock or cond fail");
break;
}
/*启动 min_thr_num 个 work thread*/
for(i = 0; i < min_thr_num; i++){
/*pool指向当前线程池*/
pthread_create(&(pool->threads[i]),NULL, threadpool_thread, (void *)pool);
printf("start thread 0x%x...\n", (unsigned int)pool->threads[i]);
}
/*创建管理者线程*/
pthread_create(&(pool->adjust_tid), NULL, adjust_thread, (void *)pool);
return pool;
}while(0);
/*前面代码调用失败时,释放pool存储空间*/
threadpool_free(pool);
return NULL;
}
子线程中的回调函数threadpool_thread
/*线程池中各个工作线程*/
void *threadpool_thread(void *threadpool){
threadpool_t *pool = (threadpool_t *)threadpool;
threadpool_task_t task;
while(true){
//刚创建出线程,等待任务队列里有任务,否则阻塞等待队列里有任务后再唤醒接收任务
pthread_mutex_lock(&(pool->lock));
//queue_size == 0 说明没有任务,调wait阻塞在条件变量上,若有任务,跳过该while
while((pool->queue_size == 0) && (!pool->shutdown)){
printf("thread 0x%x is waiting\n", (unsigned int)pthread_self());
pthread_cond_wait(&(pool->queue_not_empty), &(pool->lock));
//清除指定数目的空闲线程,若要结束的线程个数大于0,结束线程
if(pool->wait_exit_thr_num > 0){
pool->wait_exit_thr_num--;
//若线程池里线程个数大于最小值时可以结束当前线程
if(pool->live_thr_num > pool->min_thr_num){
printf("thread 0x%x is exiting\n", (unsigned int)pthread_self());
pool->live_thr_num--;
pthread_mutex_unlock(&(pool->lock));
pthread_exit(NULL);
}
}
}
}
}
管理者线程回调函数adjust_thread
根据DEFAULT_TIME循环执行一次,根据既定算法,判断是否应该创建、销毁线程池中 指定步长的线程。
#define DEFAULT_TIME 10 //10s检测一次
//管理线程
void *adjust_thread(void *threadpool){
int i;
threadpool_t *pool = (threadpool_t *)threadpool;
while(!pool->shutdown){
//定时, 对线程池管理
sleep(DEFAULT_TIME);
pthread_mutex_lock(&(pool->lock));
//关注 任务数
int queue_size = pool->queue_size;
//存活 线程数
int live_thr_num = pool->live_thr_num;
pthread_mutex_unlock(&(pool->lock));
pthread_mutex_lock(&(pool->thread_counter));
//忙着的线程数
int busy_thr_num = pool->busy_thr_num;
pthread_mutex_unlock(&(pool->thread_counter));
//创建新线程 算法:任务数大于最小线程池个数,且存活的线程数少于最大线程个数时
if(queue_size >= MIN_WAIT_TASK_NUM && live_thr_num < pool->max_thr_num){
pthread_mutex_lock(&(pool->lock));
int add = 0;
//一次增加 DEFAULT_THREAD 个线程
for(i = 0; i < pool->max_thr_num && add < DEFAULT_THREAD_VARY
&& pool->live_thr_num < pool->max_thr_num; i++){
if(pool->threads[i] == 0 || !is_thread_alive(pool->threads[i])){
pthread_create(&(pool->threads[i]), NULL, threadpool_thread, (void *)pool);
add++;
pool->live_thr_num++;
}
}
pthread_mutex_unlock(&(pool->lock));
}
//销毁多余的空闲线程算法:忙线程*2 小于 存活的线程数 且 存活的线程数 大于 最小线程数时
if((busy_thr_num * 2) < live_thr_num && live_thr_num > pool->min_thr_num){
//一次销毁DEFAULT_THREAD个线程,随机10个即可
pthread_mutex_lock(&(pool->lock));
//要销毁的线程数 设置为10
pool->wait_exit_thr_num = DEFAULT_THREAD_VARY;
pthread_mutex_unlock(&(pool->lock));
for(i = 0; i < DEFAULT_THREAD_VARY; i++){
pthread_cond_signal(&(pool->queue_not_empty));
}
}
}
return NULL;
}
threadpool_add函数
//线程池中的线程 模拟处理业务
void *process(void *arg){
printf("thread 0x%x working on task %d\n", (unsigned int)pthread_self(),(int)arg);
//线程实际需处理的函数
print("task %d is end\n", (int)arg);
return NULL;
}
int threadpool_add(threadpool_t *pool, void*(*function)(void *arg), void *arg){
pthread_mutex_lock(&(pool->lock));
// ==为真,队列已经满,调wait阻塞
while((pool->queue_size == pool->queue_max_size) && (!pool->shutdown)){
pthread_cond_wait(&(pool->queue_not_full), &(pool->lock));
}
if(pool->shutdown){
pthread_cond_broadcast(&(pool->queue_not_empty));
pthread_mutex_unlock(&(pool->lock));
return 0;
}
//清空工作线程 调用的回调函数 的参数arg
if(pool->task_queue[pool->queue_rear].arg != NULL){
pool->task_queue[pool->queue_rear].arg != NULL;
}
//添加任务到任务队列里
pool->task_queue[pool->queue_rear].function = function;
pool->task_queue[pool->queue_rear].arg = arg;
//队尾指针移动,模拟环形队列
pool->queue_rear = (pool->queue_rear + 1)% pool->queue_max_size;
pool->queue_size++;
//添加完成任务后,队列不为空,唤醒线程池中 等待处理任务的线程
pthread_cond_signal(&(pool->queue_not_empty));
pthread_mutex_unlock(&(pool->lock));
return 0;
}
threadpool_destory函数
int threadpool_destory(threadpool_t *pool){
int i;
if(pool == NULL){
return -1;
}
pool->shutdown = true;
//先销毁管理线程
pthread_join(pool->adjust_tid, NULL);
for(i = 0; i < pool->live_thr_num ; i++){
//通知所有的空闲线程
pthread_cond_broadcast(&(pool->queue_not_empty));
}
for(i = 0; i < pool->live_thr_num; i++){
pthread_join(pool->threads[i], NULl);
}
threadpool_free(pool);
return 0;
}
threadpool_free函数
int threadpool_free(threadpool_t *pool){
if(pool == NULL){
return -1;
}
if(pool->task_queue){
free(pool->task_queue);
}
if(pool->threads){
free(pool->threads);
pthread_mutex_lock(&(pool->lock));
pthread_mutex_destory(&(pool->lock));
pthread_mutex_lock(&(pool->thread_counter));
pthread_mutex_destory(&(pool->thread_counter));
pthread_cond_destory(&(pool->queue_not_empty));
pthread_cond_destory(&(pool->queue_not_full));
}
free(pool);
pool = NULL;
return 0;
}