C语言实现一个简单的线程池

来源:互联网 发布:关系数据库的第三范式 编辑:程序博客网 时间:2024/04/26 09:01

(代码有参考网上的一些实现)还有几个功能需要慢慢的实现和一些bug需要改,比如实现线程池的动态增长:

详细请看我的github: https://github.com/chengshuguang/thread-pool


thread_pool.h

#ifndef THREAD_POOL_H#define THREAD_POOL_H#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <pthread.h>typedef struct task{void *(*taskfunc)(void *arg);//声明一个函数指针void *arg;//函数的参数struct task *next;}task;typedef struct thread_pool{task *task_queue_head;//任务队列task *task_queue_end;//指向任务队列结尾int task_queue_size;pthread_t *thread_queue;//线程队列int thread_num;int idle_thread_num;//空闲线程数int is_pool_destroyed;pthread_mutex_t queue_mutex;//用来互斥访问任务队列pthread_cond_t queue_cond;}thread_pool;#ifdef __cplusplusextern "C"{#endifextern thread_pool *pool;extern int thread_pool_init(int thread_pool_size);//extern void * thread_pool_entrance(void *arg);extern int thread_pool_add_task(void *(*taskfunc)(void *arg), void *arg);extern int thread_pool_destroy();#ifdef __cplusplus}#endif#endif //THREAD_POOL_H

thread_pool.c

#include "thread_pool.h"#include <pthread.h>thread_pool *pool = NULL;void * thread_pool_entrance(void *arg){int thread_id = (int)arg;printf("thread %d is created\n",thread_id);while(1){pthread_mutex_lock(&(pool->queue_mutex));while(pool->task_queue_size == 0 && !pool->is_pool_destroyed)//必须用while,防止假唤醒{pthread_cond_wait(&(pool->queue_cond),&(pool->queue_mutex));//等待的时候会解锁,唤醒后加锁}if(pool->is_pool_destroyed){printf("thread %d exit!!!\n",thread_id);pthread_mutex_unlock(&(pool->queue_mutex));//中途退出最容易出错,注意要解锁pthread_exit(NULL);}pool->idle_thread_num--;//线程进入忙碌状态//从任务队列中取出任务task *work;work = pool->task_queue_head;pool->task_queue_head = pool->task_queue_head->next;if(pool->task_queue_head == NULL)pool->task_queue_end = NULL;pool->task_queue_size--;pthread_mutex_unlock(&(pool->queue_mutex));//回调函数(*(work->taskfunc))(work->arg);pool->idle_thread_num++;//线程空闲}return NULL;}int thread_pool_init(int thread_pool_size){pool = (thread_pool *)malloc(sizeof(thread_pool));//不要最先给线程池分配空间pool->is_pool_destroyed = 0;pool->task_queue_head = NULL;pool->task_queue_end = NULL;pool->task_queue_size = 0;pool->thread_num = thread_pool_size;pool->thread_queue = (pthread_t *)malloc(thread_pool_size * sizeof(pthread_t));pool->idle_thread_num = thread_pool_size;//创建线程int i, ret;for(i=0; i<thread_pool_size; i++){ret = pthread_create(&(pool->thread_queue[i]), NULL, thread_pool_entrance, (void *)i);if(ret < 0){printf("thread create error!!!\n");thread_pool_destroy();//注意销毁,避免内存泄漏return -1;}}pthread_mutex_init(&(pool->queue_mutex), NULL);pthread_cond_init(&(pool->queue_cond), NULL);return 0;}typedef void *(*taskfunc)(void *arg);int thread_pool_add_task(taskfunc func, void *arg){task *newtask;newtask = (task *)malloc(sizeof(task));newtask->taskfunc = func;newtask->arg = arg;newtask->next = NULL;pthread_mutex_lock(&(pool->queue_mutex));if(pool->task_queue_head == NULL){pool->task_queue_head = pool->task_queue_end = newtask;}else{pool->task_queue_end = pool->task_queue_end->next = newtask;}pool->task_queue_size++;pthread_cond_signal(&(pool->queue_cond));pthread_mutex_unlock(&(pool->queue_mutex));return 0;}int thread_pool_destroy(){if(pool->is_pool_destroyed)//防止多次销毁return -1;pool->is_pool_destroyed = 1;pthread_cond_broadcast(&(pool->queue_cond));//通知所有线程线程池销毁了int i;for(i=0; i<pool->thread_num; i++)//等待线程全部执行完pthread_join(pool->thread_queue[i], NULL);//销毁任务队列task *temp = NULL;while(pool->task_queue_head){temp = pool->task_queue_head;pool->task_queue_head = pool->task_queue_head->next;free(temp);}//pool->task_queue_head = NULL;//pool->task_queue_end = NULL;//销毁线程队列free(pool->thread_queue);pool->thread_queue = NULL;pthread_mutex_destroy(&(pool->queue_mutex));pthread_cond_destroy(&(pool->queue_cond));free(pool);pool = NULL;return 0;}

test.c

#include "thread_pool.h"#include <stdio.h>void *taskprocess(void *arg){printf("aaaaaadoing tasksaaaaaaaaa\n");usleep(1000);return NULL;}int main(){thread_pool_init(5);int i;for(i=1; i<=10; i++){thread_pool_add_task(taskprocess,(void *)i);usleep(1000);}sleep(1);thread_pool_destroy();return 0;}