Cスレッドプール

7166 ワード

大神の考え方を参考にして、理解を強化することを書きます.
#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!
"
); return -1; } if(pthread_cond_init(&pool->empty,NULL)){ printf("cond init fail!
"
); return -1; } if(pthread_cond_init(&pool->not_empty,NULL)){ printf("cond init fail!
"
); return -1; } if(pthread_cond_init(&pool->not_full,NULL)){ printf("cond init fail!
"
); 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!
"
); return -1; } int i; for(i=0;itid[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!
"
); pthread_mutex_unlock(&pool->ready); pthread_exit(NULL); } // printf("now cur_job_num:%d
"
,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
"
,*(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;imax_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()状態量の数は、対応するロックの数と一致しており、もちろん、非対応状態のロックは、この列の条件ロックの使用ではない