线程池思路

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,以此实现优雅的退出。
posted @ 2022-03-18 09:07  晓风霜度-  阅读(60)  评论(0)    收藏  举报