简单的thread_pool代码

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>

#define DEFAULT_THREAD_NUM 4

typedef struct job_s {
    void *(*process)(void*);
    void *arg;
    struct job_s *next;
}job_t;

typedef struct thread_pool_s {
    pthread_mutex_t queue_lock;
    pthread_cond_t  queue_ready;
    job_t           *queue_head;
    unsigned int    cur_queue_size;
    pthread_t       *tids;
    unsigned int    max_thread_num;
    int             shutdown;
}thread_pool_t;

thread_pool_t *pool = NULL;

void *thread_routine(void *arg) {
    printf("thread 0x%x is starting.\n", (unsigned int)pthread_self());
    while (1) {
        pthread_mutex_lock(&(pool->queue_lock));
        while (0 == pool->cur_queue_size && 0 == pool->shutdown) {
            printf("thread 0x%x is waiting.\n", (unsigned int)pthread_self());
            pthread_cond_wait(&(pool->queue_ready), &(pool->queue_lock));
        }
        if (pool->shutdown) {
            pthread_mutex_unlock(&(pool->queue_lock));
            printf("thread 0x%x will exit.\n", (unsigned int)pthread_self());
            pthread_exit(NULL);
        }
        job_t *temp = pool->queue_head;
        pool->queue_head = temp->next;
        pool->cur_queue_size--;
        pthread_mutex_unlock(&(pool->queue_lock));
        (*temp->process)(temp->arg);
        free(temp);
    }
    return NULL;
}

int thread_pool_init(int max_thread_num) {// initialize by the order defined
    int i;
    if (max_thread_num <= 0)
        max_thread_num = DEFAULT_THREAD_NUM;
    pool = (thread_pool_t*)malloc(sizeof(thread_pool_t));
    if (NULL == pool)
        return -1;
    pthread_mutex_init(&(pool->queue_lock), NULL);
    pthread_cond_init(&(pool->queue_ready), NULL);
    pool->queue_head = NULL;
    pool->cur_queue_size = 0;
    pool->tids = (pthread_t*)malloc(max_thread_num * sizeof(pthread_t));
    if (NULL == pool->tids) {
        free(pool);
        pool = NULL;
        return -1;
    }
    for (i = 0; i < max_thread_num; i++) {
        printf("thread 0x%x is creating.\n", (unsigned int)pthread_self());
        pthread_create(&(pool->tids[i]), NULL, (void*)thread_routine, NULL);
    }
    pool->shutdown = 0;
    return 1;
}

int thread_pool_add(void *(*process)(void*), void *arg) {
    job_t *temp = (job_t*)malloc(sizeof(job_t));
    temp->process = process;
    temp->arg = arg;
    temp->next = NULL;
    pthread_mutex_lock(&(pool->queue_lock));
    if (NULL == pool->queue_head) {
        pool->queue_head = temp;
    } else {
        job_t *p = pool->queue_head;
        while (p->next) 
            p = p->next;
        p->next = temp;
    }
    pool->cur_queue_size++;
    pthread_cond_signal(&(pool->queue_ready));
    pthread_mutex_unlock(&(pool->queue_lock));
    return 0;
}

int thread_pool_destroy() {// 0 means success and -1 means failed.
    int i;
    if (pool->shutdown)
        return -1;
    pthread_cond_broadcast(&(pool->queue_ready));
    for (i = 0; i < pool->max_thread_num; i++)
        pthread_join(pool->tids[i], NULL);
    free(pool->tids);
    job_t *p = pool->queue_head;
    while (p) {
        pool->queue_head = p->next;
        free(p);
        p = pool->queue_head;
    }
    pool->shutdown = 1;
    //pthread_mutex_destory(&(pool->queue_lock));
    //pthread_cond_destory(&(pool->queue_ready));
    free(pool);
    pool = NULL;
    return 0;
}

void *my_process(void *arg) {
    printf("thread 0x%x is working on task %d.\n", (unsigned int)pthread_self(), *(int*)arg);
    sleep(1);
    return NULL;
}

int main(int argc, char *argv[]) {
    int i;
    thread_pool_init(3);
    int *datas = (int*)malloc(sizeof(int) * 10);
    for (i = 0; i < 10; i++) {
        datas[i] = i;
        thread_pool_add(my_process, (datas + i));
    }
    sleep(5);
    thread_pool_destroy();
    free(datas);
    return 0;
}

你可能感兴趣的:(简单的thread_pool代码)