1. 程式人生 > 其它 >執行緒池思路

執行緒池思路

1、makefile

SRCS:=$(wildcard *.c)
OBJS:=$(SRCS:%.c=%.o)
CC:=gcc
server:$(OBJS)
    $(CC) $^ -o $@ -lpthread
%.o:%.c
    $(CC) -c $^ -o $@ -g 
.PHONY:clean rebuild
clean:
    $(RM) $(OBJS) server 
rebuild:clean server

2、終端輸入設計

./server ip port 工作執行緒數量   3、建立執行緒池

threadPool_t threadPool;
threadPoolInit(&threadPool,workerNum);

  4、建立工作執行緒  int workerNum = atoi(argv[3]);  makeWorker(&threadPool);   5、tcp連線 tcpInit(argv[1],argv[2],&sockFd);   6、建立epoll監聽,子程序監聽網路socket與父程序管道exitPipe[0]讀端

int epfd = epoll_create(10);
epollAdd(sockFd,epfd);
epollAdd(exitPipe[0],epfd);
struct epoll_event readyList[2];

7、工作執行緒實現,從事件佇列中取任務(共享資源區域需上鎖,且從佇列任務中取出後任務佇列自然要把它dequeue)

while(1){
        int netFd;
        pthread_mutex_lock(&pThreadPool->mutex);
        pthread_cleanup_push(unlock,&pThreadPool->mutex);
        while(pThreadPool->taskQueue.size == 0 && pThreadPool->isThreadPoolRunning == 1){
            pthread_cond_wait(&pThreadPool->cond,&pThreadPool->mutex);
        }
        
if(pThreadPool->isThreadPoolRunning == 0){ puts("child quit"); pthread_exit(NULL);//不能用return,與cleanup衝突 } puts("GetTask"); netFd = pThreadPool->taskQueue.pFront->netFd; deQueue(&pThreadPool->taskQueue); pthread_cleanup_pop(1); handleEvent(netFd); printf("thread done!, tid = %lu\n", pthread_self());

 

8、主程序與子程序直接管道通訊,主程序專門負責接收訊號 int exitPipe[2]; pipe(exitPipe);   9、上鎖,條件訊號,資源清理函式(cleanup避免子執行緒帶鎖而死),全域性變數isThreadPoolRunning,以此實現優雅的退出。