#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代码
最新推荐文章于 2023-09-05 02:31:57 发布