线程池的实现
线程池的组成
工作原理
- 避免线程创建销毁切换带来的开销,多个线程同时存在,在有新任务到来的情况下,线程根据当前所处状态去竞争待处理的任务资源,成功获取到任务之后执行并返回,再重新进入等待新任务到来的状态
实现思路
- 线程池创建时,同时创建N个线程
- 线程池对象内部实现一个任务队列,用于保存待执行的任务对象
- 外部线程可以调用开放接口添加待处理任务
- 开放接口还包括线程池的创建和销毁
线程池中类型定义
typedef struct _worker
{
pthread_t pthread_id;
int terminated;
struct _threadpool *pool;
struct _worker *prev;
struct _worker *next;
}WORKER;
typedef struct _job // 任务队列的节点
{
void (*func)(struct _job *arg);
void *user_data;
struct _job *next;
struct _job *prev;
}JOB;
typedef struct _threadpool
{
WORKER *workers;
JOB *jobs;
pthread_cond_t cond;
pthread_mutex_t mutex;
}THREADPOOL;
#define ADD_ITEM(item, list) do{ \
item->prev = NULL; \
item->next = list; \
if(list != NULL) list->prev = item; \
list = item; \
} while (0);
#define DEL_ITEM(item, list) do{ \
if(list->prev != NULL) list->prev->next = item->next; \
if(list->next != NULL) list->next->prev = item->prev; \
if(item == list) list = item->next; \
item->prev = NULL; \
item->next = NULL; \
} while (0);
创建一个线程池
void *threadCallback(void *arg)
{
WORKER *worker = (WORKER *)arg;
while(1)
{
pthread_mutex_lock(&worker->pool->mutex);
while(worker->pool->jobs == NULL)
{
pthread_cond_wait(&worker->pool->cond, &worker->pool->mutex);
}
if(worker->terminated)
{
pthread_mutex_unlock(&worker->pool->mutex);
break;
}
JOB *job = worker->pool->jobs;
if(job)
DEL_ITEM(job, worker->pool->jobs);
pthread_mutex_unlock(&worker->pool->mutex);
if(job == NULL) continue;
job->func(job);
}
free(worker);
worker = NULL;
}
int thread_pool_create(THREADPOOL *pool, int threadNum)
{
if(pool == NULL) return 0;
if(threadNum < 1) threadNum = 1;
pthread_cond_init(&pool->cond, NULL);
pthread_mutex_init(&pool->mutex, NULL);
int idx = 0;
for(idx = 0; idx < threadNum; idx++)
{
WORKER *worker = (WORKER *) malloc(sizeof(WORKER));
if(worker == NULL)
{
perror("worker allocation failed\n");
return idx;
}
memset(worker, 0, sizeof(WORKER));
int ret = pthread_create(&worker->pthread_id, NULL, threadCallback, worker);
if(ret)
{
perror("pthread_create failed\n");
free(worker);
worker = NULL;
return idx;
}
worker->pool = pool;
ADD_ITEM(worker, pool->workers);
}
return idx;
}
销毁一个线程池
void thread_pool_destroy(THREADPOOL* pool)
{
WORKER* worker = NULL;
for(worker = pool->workers; worker != NULL; worker = worker->next)
{
worker->terminated = 1;
}
pthread_mutex_lock(&worker->pool->mutex);
pthread_cond_broadcast(&worker->pool->cond);
pthread_mutex_unlock(&worker->pool->mutex);
}
添加任务
int thread_pool_push_task(THREADPOOL *pool, JOB *job)
{
if(job == NULL) return 0;
pthread_mutex_lock(&pool->mutex);
ADD_ITEM(job, pool->jobs);
pthread_mutex_unlock(&pool->mutex);
pthread_cond_signal(&pool->cond);
}
测试代码
#define POOL_MAX_ 50
#define TASK_MAX_ 1000
void jobFunc(JOB *job)
{
int value = *(int *)job->user_data;
printf("value : %d , selfid : %lu \n", value, pthread_self());
free(job);
job = NULL;
}
void main(int argc, char *argv[])
{
THREADPOOL pool = {0};
int ret = thread_pool_create(&pool, POOL_MAX_);
if(ret != POOL_MAX_)
{
perror("pool_create failed\n");
return;
}
for(int i = 0; i < TASK_MAX_; i++)
{
JOB *job = (JOB *)malloc(sizeof(JOB));
job->func = jobFunc;
job->user_data = malloc(sizeof(int));
*(int *)job->user_data = i;
thread_pool_push_task(&pool, job);
}
getchar();
}
测试效果
终端输出以下内容
value : 134 , selfid : 140526279378496
value : 133 , selfid : 140526287771200
value : 132 , selfid : 140526270985792
value : 131 , selfid : 140526254200384
value : 402 , selfid : 140526245807680
value : 556 , selfid : 140526237414976
value : 658 , selfid : 140526262593088
value : 812 , selfid : 140526229022272
value : 863 , selfid : 140526220629568
value : 862 , selfid : 140526212236864
value : 861 , selfid : 140526195451456
value : 999 , selfid : 140526187058752
value : 998 , selfid : 140526203844160
value : 997 , selfid : 140526170273344
value : 996 , selfid : 140526178666048
value : 995 , selfid : 140526161880640
value : 994 , selfid : 140526153487936
value : 993 , selfid : 140526145095232
value : 992 , selfid : 140526128309824
value : 991 , selfid : 140526119917120
value : 989 , selfid : 140526136702528
value : 988 , selfid : 140526103131712
value : 987 , selfid : 140526094739008
value : 986 , selfid : 140526086346304
value : 985 , selfid : 140526077953600
value : 984 , selfid : 140526061168192
value : 983 , selfid : 140526052775488
value : 982 , selfid : 140526069560896
value : 981 , selfid : 140526035990080
value : 980 , selfid : 140526044382784
value : 979 , selfid : 140526027597376
value : 978 , selfid : 140526010811968
value : 977 , selfid : 140526002419264
value : 976 , selfid : 140525994026560
value : 975 , selfid : 140526019204672
value : 974 , selfid : 140525985633856
value : 973 , selfid : 140525977241152
value : 972 , selfid : 140525943670336
value : 971 , selfid : 140525918492224
value : 136 , selfid : 140526296163904
value : 968 , selfid : 140525910099520
...