参考大神思路,写下加强理解。
#include "pthread.h"
#include "stdio.h"
#include "stdlib.h"
struct Job{
void*(*callback_function)(void*);
void* arg;
Job* next;
Job():next(NULL){}
};
struct threadpool{
pthread_mutex_t ready;
pthread_cond_t empty,not_empty,not_full;
int max_job_num,cur_job_num;
struct Job*head,*tail;
pthread_t *tid;
int closepool;
int status;
};
int threadpool_init(threadpool*pool);
int threadpool_add_job(threadpool*pool,void*(*work)(void*),void*arg);
int threadpool_destroy(threadpool*pool);
void* threadpool_deal(void*arg);
//实现
int threadpool_init(threadpool*pool,int max){
if(pthread_mutex_init(&pool->ready,NULL)){
printf("mutex init fail!\n");
return -1;
}
if(pthread_cond_init(&pool->empty,NULL)){
printf("cond init fail!\n");
return -1;
}
if(pthread_cond_init(&pool->not_empty,NULL)){
printf("cond init fail!\n");
return -1;
}
if(pthread_cond_init(&pool->not_full,NULL)){
printf("cond init fail!\n");
return -1;
}
pool->max_job_num=max;
pool->cur_job_num=0;
pool->head=NULL;
pool->tail=NULL;
pool->closepool=0;
pool->status=0;
pool->tid=(pthread_t*)malloc(max*sizeof(pthread_t));
if(pool->tid==NULL){
printf("malloc fail!\n");
return -1;
}
int i;
for(i=0;i<max;i++){
pthread_create(&pool->tid[i],NULL,threadpool_deal,(void*)pool);
}
return 0;
}
int threadpool_add_job(threadpool*pool,void*(*work)(void*),void*arg){
pthread_mutex_lock(&pool->ready);
while(pool->cur_job_num==pool->max_job_num)pthread_cond_wait(&pool->not_full,&pool->ready);
if(pool->closepool){
pthread_mutex_unlock(&pool->ready);
return -1;
}
struct Job*job=(Job*)malloc(sizeof(Job));
job->callback_function=work;
job->arg=arg;
if(pool->head==NULL){
pool->head=job;
pool->tail=job;
}else{
pool->tail->next=job;
pool->tail=pool->tail->next;
}
pool->cur_job_num++;
if(pool->cur_job_num==1)pthread_cond_broadcast(&pool->not_empty);
pthread_mutex_unlock(&pool->ready);
return 0;
}
void* threadpool_deal(void*arg){
threadpool* pool=(threadpool*)arg;
while(1){
pthread_mutex_lock(&pool->ready);
while(pool->cur_job_num==0&&pool->closepool==0)pthread_cond_wait(&pool->not_empty,&pool->ready);
if(pool->closepool&&pool->cur_job_num==0){
// printf("i have exited!\n");
pthread_mutex_unlock(&pool->ready);
pthread_exit(NULL);
}
// printf("now cur_job_num:%d\n",pool->cur_job_num);
struct Job*job=pool->head;
if(pool->cur_job_num==1){
pool->head=NULL;
pool->tail=NULL;
}else{
pool->head=pool->head->next;
}
pool->cur_job_num--;
if(pool->cur_job_num==pool->max_job_num-1)pthread_cond_broadcast(&pool->not_full);
if(pool->cur_job_num==0)pthread_cond_signal(&pool->empty);
pthread_mutex_unlock(&pool->ready);
// printf("job canshu:%d\n",*(int*)job->arg);
(*(job->callback_function))(job->arg);
free(job);
}
}
int threadpool_destroy(threadpool*pool){
pthread_mutex_lock(&pool->ready);
pool->closepool=1;
int i;
while(pool->cur_job_num!=0){
pthread_cond_wait(&pool->empty,&pool->ready);
}
pthread_cond_broadcast(&pool->not_empty);
pthread_cond_broadcast(&pool->not_full);
pthread_mutex_unlock(&pool->ready);
for(i=0;i<pool->max_job_num;i++){
pthread_join(pool->tid[i],NULL);
}
free(pool->tid);
pthread_cond_destroy(&pool->empty);
pthread_cond_destroy(&pool->not_empty);
pthread_cond_destroy(&pool->not_full);
pthread_mutex_destroy(&pool->ready);
free(pool);
return 0;
}
(我的代码风格糟糕。。非常糟糕。。)
学习要点:
线程复用的实现
pthread_cond_broadcast()与pthread_cond_signal()
状态量的数目与相应锁的数目保持一致,当然,非对应状态的锁不在此列
条件锁的使用