//threadpool.h #ifndef __THREADPOOL_H__ #define __THREADPOOL_H__ #include <pthread.h> typedef void* (*task_fun)(void*); //用鏈表來維護等待任務 typedef struct threadtask { //任務的執行函數 task_fun task; //執行函數的參數 void* arg; //下一節點 struct threadtask* next; }THREAD_TASK; void* thr_fun(void* arg);//每個線程執行的函數 int init_task(void);//初始化等待任務鏈表 int init_pool(void);//初始化線程池 //向任務鏈表中新增工作 int add_task(task_fun task, void* arg); int destroy_poll(void); #endif
//threadpool.c //對於基本不出現的錯誤不進行檢測 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include "threadpool.h" //線程池中最多允許的線程數 #define THREADPOOLSIZE 3 //當前等待任務的個數 static unsigned int taskwaittingnum=0; //taskwaittingnum的鎖 pthread_mutex_t g_nummutex= PTHREAD_MUTEX_INITIALIZER; //等待任務隊列的鎖 pthread_mutex_t g_taskmutex=PTHREAD_MUTEX_INITIALIZER; THREAD_TASK* g_pTask=NULL; pthread_t tid[THREADPOOLSIZE]; //是否銷毀線程池 static int isShut=0; void* thr_fun(void* arg) { task_fun task; void* funarg=NULL; THREAD_TASK* ptmp=NULL; while(1) { //如果要銷毀線程池,跳出while迴圈 if( 1==isShut ) { break;//跳出while迴圈 } pthread_mutex_lock(&g_nummutex); //如果當前沒有任務需要調度,休眠5000微妙 if( 0==taskwaittingnum ) { pthread_mutex_unlock(&g_nummutex); usleep(5000); continue; } //當前有任務調度 else { //需要寫入鏈表,所以要鎖定鏈表 pthread_mutex_lock(&g_taskmutex); task=g_pTask->next->task; funarg=g_pTask->next->arg; ptmp=g_pTask->next; g_pTask->next=ptmp->next; taskwaittingnum--; pthread_mutex_unlock(&g_taskmutex); pthread_mutex_unlock(&g_nummutex); free(ptmp); ptmp=NULL; (*task)(funarg); } } pthread_exit(NULL); } //初始化任務鏈表,首個節點不用來儲存任務 int init_task(void) { g_pTask=(THREAD_TASK*)malloc(sizeof(THREAD_TASK)); if( NULL==g_pTask ) { printf("init_task malloc fails./n"); return -1; } memset(g_pTask, 0, sizeof(THREAD_TASK)); g_pTask->next=NULL; return 0; } //初始化線程池 int init_pool(void) { int ret; int i; for( i=0 ; i<THREADPOOLSIZE ; i++ ) { ret=pthread_create(tid+i, NULL, thr_fun, NULL); if( ret!=0 ) { printf("init_pool pthread_create:/n%s/n", strerror(ret)); return -1; } } return 0; } int add_task(task_fun task, void* arg) { THREAD_TASK* ptmp=NULL; pthread_mutex_lock(&g_nummutex); pthread_mutex_lock(&g_taskmutex); ptmp=g_pTask; while( ptmp->next!=NULL ) { ptmp=ptmp->next; } ptmp->next=(THREAD_TASK*)malloc(sizeof(THREAD_TASK)); if( NULL==ptmp->next ) { printf("add_task malloc fails/n"); return -1; } ptmp=ptmp->next; ptmp->task=task; ptmp->arg=arg; ptmp->next=NULL; taskwaittingnum++; pthread_mutex_unlock(&g_nummutex); pthread_mutex_unlock(&g_taskmutex); return 0; } int destroy_pool(void) { isShut=1; pthread_mutex_destroy(&g_nummutex); pthread_mutex_destroy(&g_taskmutex); return 0; }
//用來測試的main.c #include <stdio.h> #include "threadpool.h" void* task1(void* arg) { printf("task1正在運行!/n"); sleep(10); printf("task1運行結束!/n"); return NULL; } void* task2(void* arg) { printf("task2正在運行!/n"); sleep(10); printf("task2運行結束!/n"); return NULL; } void* task3(void* arg) { printf("task3正在運行!/n"); printf("task3運行結束!/n"); return NULL; } void* task4(void* arg) { printf("task4正在運行!/n"); printf("task4運行結束!/n"); return NULL; } int main(int argc, char *argv[]) { init_task(); init_pool(); add_task(task1, NULL); add_task(task2, NULL); add_task(task3, NULL); add_task(task4, NULL); sleep(30); destroy_pool(); return 0; }