线程池的简单使用
参考代码:
测试结果:
#ifndef _THREAD_POOL
#define _THREAD_POOL
#include <pthread.h>
/* linklist of task */
typedef struct tpool_work
{
void* (*routine)(void *); // function of task
void *arg; // argument of task function
struct tpool_work *next;
}tpool_work_t;
typedef struct tpool
{
int shutdown; // flag of pthread_pool destroyed or not (1/0)
int max_thr_num; // max number of pthread
pthread_t *tid; // pthread ID array
tpool_work_t *queue_head; // linklist of pthread
pthread_mutex_t queue_lock;
pthread_cond_t queue_ready;
}tpool_t;
/*
*
*@brief create a pthread
*@param max_thr_num
*@return 0: success, other: failed
*
*/
int tpool_create(int max_thr_num);
/*
*
*@brief destroy pthread pool
*
*/
void tpool_destroy();
/*
*
*@brief add a pthread to pool
*@param routine function pointer
*@param arg
*@return 0: success, other: failed
*
*/
int tpool_add_work(void* (*routine)(void *), void *arg);
#endif
/*
* filename: pthreadpool.c
*
* time: 2014-8-31
*/
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "pthreadpool.h"
static tpool_t *tpool = NULL;
/* function of pthread processing */
static void* thread_routine(void *arg)
{
tpool_work_t *work;
while(1)
{
pthread_mutex_lock(&tpool->queue_lock);
/* wait for pthreadpool to be destroyed */
//while(!tpool->queue_head && !tpool->shutdown)
while((tpool->queue_head == NULL) && (tpool->shutdown == 0))
{
pthread_cond_wait(&tpool->queue_ready, &tpool->queue_lock);
}
//if(tpool->shutdown)
if(tpool->shutdown == 1)
{
pthread_mutex_unlock(&tpool->queue_lock);
pthread_exit(NULL);
}
work = tpool->queue_head;
tpool->queue_head = tpool->queue_head->next;
pthread_mutex_unlock(&tpool->queue_lock);
work->routine(work->arg);
if(work != NULL)
{
free(work);
work = NULL;
}
}
return NULL;
}
/*
*
*@brief create a pthread
*@param max_thr_num
*@return 0: success, other: failed
*
*/
int tpool_create(int max_thr_num)
{
int i = 0;
tpool = calloc(1, sizeof(tpool_t));
if(NULL == tpool)
{
printf("%s: calloc failed\n", __FUNCTION__);
exit(1);
}
tpool->max_thr_num = max_thr_num;
tpool->shutdown = 0;
tpool->queue_head = NULL;
if(pthread_mutex_init(&tpool->queue_lock, NULL) != 0)
{
printf("%s: pthread_mutex_init failed, errno: %d, error: %s\n",
__FUNCTION__, errno, strerror(errno));
exit(1);
}
if(pthread_cond_init(&tpool->queue_ready, NULL) != 0)
{
printf("%s: pthread_cont_init failed, errono: %d, error: %s\n",
__FUNCTION__, errno, strerror(errno));
exit(1);
}
tpool->tid = calloc(max_thr_num, sizeof(pthread_t));
if(NULL == tpool->tid)
{
printf("%s: calloc failed\n", __FUNCTION__);
exit(1);
}
for(i=0; i<max_thr_num; i++)
{
if(pthread_create(&tpool->tid[i], NULL, thread_routine, NULL) != 0)
{
printf("%s: pthread_create failed, errno: %d, error: %s\n",
__FUNCTION__, errno, strerror(errno));
exit(1);
}
}
return 0;
}
/*
*
*@brief destroy pthread pool
*
*/
void tpool_destroy()
{
int i = 0;
tpool_work_t *member = NULL;
//if(tpool->shutdown)
if(tpool->shutdown == 1)
{
return ;
}
tpool->shutdown = 1;
/* broaccast to the pthread who is waiting */
pthread_mutex_lock(&tpool->queue_lock);
pthread_cond_broadcast(&tpool->queue_ready);
pthread_mutex_unlock(&tpool->queue_lock);
for(i=0; i<tpool->max_thr_num; i++)
{
pthread_join(tpool->tid[i], NULL);
}
if(NULL != tpool->tid)
{
free(tpool->tid);
tpool->tid = NULL;
}
while(tpool->queue_head != NULL)
{
member = tpool->queue_head;
tpool->queue_head = tpool->queue_head->next;
if(NULL != member)
{
free(member);
}
}
pthread_mutex_destroy(&tpool->queue_lock);
pthread_cond_destroy(&tpool->queue_ready);
if(NULL != tpool)
{
free(tpool);
tpool = NULL;
}
}
/*
*
*@brief add a pthread to pool
*@param routine function pointer
*@param arg
*@return 0: success, other: failed
*
*/
int tpool_add_work(void* (*routine)(void *), void *arg)
{
tpool_work_t *work = NULL;
tpool_work_t *member = NULL;
if(NULL == routine)
{
printf("%s :invalid argument\n", __FUNCTION__);
return -1;
}
work = malloc(sizeof(tpool_work_t));
if(NULL == work)
{
printf("%s : malloc failed\n", __FUNCTION__);
return -1;
}
work->routine = routine;
work->arg = arg;
work->next = NULL;
pthread_mutex_lock(&tpool->queue_lock);
member = tpool->queue_head;
if(NULL == member)
{
tpool->queue_head = work;
}
else
{
while(member->next != NULL)
{
member = member->next;
}
member->next = work;
}
/* send sinal to all pthread */
pthread_cond_signal(&tpool->queue_ready);
pthread_mutex_unlock(&tpool->queue_lock);
return 0;
}
void *func(void *arg)
{
printf("pthread: [%d]\n", (int)arg);
return NULL;
}
int main(int argc, char *argv[])
{
int i = 0;
if(tpool_create(10) != 0)
{
printf("tpool_create failed\n");
exit(1);
}
for(i=0; i<15; i++)
{
tpool_add_work(func, (void *)i);
}
sleep(2);
tpool_destroy();
return 0;
}
测试结果: