#ifndef THREADPOOL_H_INCLUDED
#define THREADPOOL_H_INCLUDED
#include <pthread.h>
typedef struct threadpool_job
{
void (*routine)(void*);
void *arg;
struct threadpool_job *next;
}threadpool_job_t;
typedef struct threadpool
{
int request_threads_num;
int act_threads_num;
int worker_threads_used;
int worker_threads_run;
pthread_t *worker_thread_ids;
pthread_mutex_t mutex;
pthread_cond_t cond;
threadpool_job_t *queue_head;
threadpool_job_t *queue_tail;
pthread_mutex_t queue_mutex;
}threadpool_t;
void *threadpool_worker_thread(void *tp);
int threadpool_init(threadpool_t *tp, int request_threads_num, int *act_threads_num);
int threadpool_destroy(threadpool_t *tp);
int threadpool_add_job(threadpool_t *tp, void (*routine)(void*),void *arg);
#endif // THREADPOOL_H_INCLUDED
/* threadpool.c */
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include "threadpool.h"
void *threadpool_worker_thread(void *tp)
{
threadpool_t *p = (threadpool_t *)tp;
threadpool_job_t *job;
void (*routine)(void *);
void *arg;
while(p->worker_threads_run)
{
pthread_mutex_lock(&p->mutex);
pthread_cond_wait(&p->cond,&p->mutex);
pthread_mutex_unlock(&p->mutex);
if (p->worker_threads_run==0) break;
pthread_mutex_lock(&p->queue_mutex);
job = p->queue_head;
if (job==NULL)
{
pthread_mutex_unlock(&p->queue_mutex);
continue;
}
p->queue_head = job->next;
if (p->queue_head==NULL) p->queue_tail = NULL;
pthread_mutex_unlock(&p->queue_mutex);
p->worker_threads_used++;
routine = job->routine;
arg = job->arg;
(*routine)(arg);
p->worker_threads_used--;
free(job);
if (p->queue_head)
{
pthread_cond_signal(&p->cond);
}
}
p->act_threads_num--;
return 0;
}
int threadpool_init(threadpool_t *tp, int request_threads_num, int *act_threads_num)
{
int i;
int ret;
tp->queue_head = NULL;
tp->queue_tail = NULL;
if ((ret = pthread_mutex_init(&tp->queue_mutex,NULL))!=0) return ret;
tp->request_threads_num = request_threads_num;
tp->worker_threads_used = 0;
tp->worker_thread_ids = (pthread_t *)calloc(request_threads_num,sizeof(pthread_t));
if ((ret = pthread_mutex_init(&tp->mutex,NULL))!=0) return ret;
if ((ret = pthread_cond_init(&tp->cond,NULL))!=0) return ret;
tp->worker_threads_run = 1;
tp->act_threads_num = 0;
for(i=0;i<request_threads_num;i++)
{
if ((ret = pthread_create(&tp->worker_thread_ids[i],NULL,threadpool_worker_thread,tp))!=0) return ret;
tp->act_threads_num++;
*act_threads_num = tp->act_threads_num;
}
return 0;
}
int threadpool_add_job(threadpool_t *tp, void (*routine)(void*),void *arg)
{
threadpool_job_t *job;
job = malloc(sizeof(threadpool_job_t));
job->routine = routine;
job->arg = arg;
job->next = NULL;
pthread_mutex_lock(&tp->queue_mutex);
if (tp->queue_head==NULL)
{
tp->queue_head = job;
}
if (tp->queue_tail)
{
tp->queue_tail->next = job;
}
tp->queue_tail = job;
pthread_mutex_unlock(&tp->queue_mutex);
pthread_cond_signal(&tp->cond);
return 0;
}
int threadpool_destroy(threadpool_t *tp)
{
while(tp->queue_head!=NULL)
{
usleep(100*1000);
}
tp->worker_threads_run = 0;
pthread_cond_broadcast(&tp->cond);
while(tp->act_threads_num>0)
{
usleep(100*1000);
}
free(tp->worker_thread_ids);
return 0;
}
本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/roc1005/archive/2010/12/02/6049695.aspx