#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pthread.h> #include <assert.h> // 任务结构体,使用队列保存 typedef struct worker_s worker_t; struct worker_s { void *(*process)(void *arg); void *arg; worker_t *next; }; // 线程池结构 typedef struct pool_s pool_t; struct pool_s { pthread_mutex_t mutex; pthread_cond_t cond; worker_t *head; worker_t *tail; pthread_t *ids; int max_thread_num; }; void *thread_cb(void *arg) { pool_t *pool = (pool_t*)arg; long self = pthread_self(); while (1) { int ret; if ((ret = pthread_mutex_lock(&pool->mutex)) != 0) { fprintf(stderr, "pthread_mutex_lock: %d\n", ret); break; } printf("in %ld\n", self); while (pool->head == NULL) { printf("wait %ld\n", self); if ((ret = pthread_cond_wait(&pool->cond, &pool->mutex)) != 0) { fprintf(stderr, "pthread_cond_wait: %d\n", ret); pthread_mutex_unlock(&pool->mutex); } } assert(pool->head != NULL); // 取出队列保存的第一个任务 worker_t *w = pool->head; pool->head = pool->head->next; pthread_mutex_unlock(&pool->mutex); w->process(w->arg); free(w); } return NULL; } pool_t *pool_init(int thread_num) { pool_t *pool = (pool_t*)malloc(sizeof(pool_t)); if (pool) { if (pthread_mutex_init(&pool->mutex, NULL) != 0) { return NULL; } if (pthread_cond_init(&pool->cond, NULL) != 0) { pthread_mutex_destroy(&pool->mutex); return NULL; } pool->head = pool->tail = NULL; pool->max_thread_num = thread_num; pool->ids = (pthread_t*)malloc(sizeof(pthread_t) * thread_num); for (int i = 0; i < thread_num; i++) { pthread_create(&pool->ids[i], NULL, thread_cb, (void*)pool); pthread_detach(pool->ids[i]); } } return pool; } int pool_add_worker(pool_t *pool, void *(*process)(void *arg), void *arg) { worker_t *w = (worker_t*)malloc(sizeof(worker_t)); if (NULL == w) { return -1; } w->process = process; w->arg = arg; w->next = NULL; pthread_mutex_lock(&pool->mutex); if (pool->head != NULL) { pool->tail->next = w; pool->tail = w; } else { pool->head = pool->tail = w; } pthread_cond_signal(&pool->cond);
pthread_mutex_unlock(&pool->mutex); return 0; } void *p_cb(void *arg) { sleep(2); printf("callback func print\n"); return NULL; } int main() { pool_t * pool = pool_init(3); for (int i = 0; i < 5; ++i) { if (pool_add_worker(pool, p_cb, NULL) != 0) { fprintf(stderr, "add worker error\n"); } } getchar(); return 0; }