代码拉取完成,页面将自动刷新
#include "head.h"
#include "threadPool.h"
// 此模块代码已经测试完成
int main(int argc, char** argv)
{
ARGS_CHECK(argc, 2);
// tcpInit 返回一个socketfd
int sockfd = tcpInit(argv[1]);
ERROR_CHECK(sockfd, -1, "tcpInit");
int reuse = 1;
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(int));
// threadPool 线程池存放子线程的tid、锁、条件变量、任务队列
threadPool_t *threadPool = calloc(1,sizeof(threadPool_t));
bzero(threadPool,sizeof(threadPool_t));
// 子线程的数量
threadPool->workerNum = 20;
// 初始化锁
pthread_mutex_init(&threadPool->mutex, NULL);
// 初始化条件变量
pthread_cond_init(&threadPool->cond, NULL);
// 存放管道描述符的int型数组
pipe(threadPool->pipefd);
// 生产workerNum个子线程
makeWorker(threadPool);
// 生产一个epollfd,用来监听socketfd
int epfd = epoll_create(1);
ERROR_CHECK(epfd , -1, "epoll_create");
// 将sockfd加入监听集合
epollAdd(epfd, sockfd);
// 将stdin加入监听集合
epollAdd(epfd, STDIN_FILENO);
while(1){
// 存放就绪集合
struct epoll_event readyEvent[2];
// 无消息阻塞,有消息返回就绪数量,此处默认为 1
int readyNum = epoll_wait(epfd, readyEvent, 20, -1);
for(int i = 0; i < readyNum; i++){
if(readyEvent[i].data.fd == sockfd){
LOGRECORD(INFO,"client requests connection");
// 接受就绪的连接, 返回与此连接关联的文件描述符
int netfd = accept(sockfd, NULL, NULL);
ERROR_CHECK(netfd, -1, "accept");
// 线程池上锁
pthread_mutex_lock(&threadPool->mutex);
// 将就绪的文件描述符放入任务队列中
Enqueue(&threadPool->taskQueue, netfd);
// 广播通知其他线程,有一个任务已经就绪
pthread_cond_broadcast(&threadPool->cond);
// 给线程池解锁
pthread_mutex_unlock(&threadPool->mutex);
}
else{
pthread_mutex_lock(&threadPool->mutex);
// 将线程退出标志改为 1
threadPool->exitFlag = 1;
// 给线程池解锁
pthread_mutex_unlock(&threadPool->mutex);
for(int i = 0; i < threadPool->workerNum; i++){
// 等待所有子线程的退出
pthread_join(threadPool->tidArr[i],NULL);
LOGRECORD(INFO,"childthread exit !");
}
// 主线程退出
pthread_exit(NULL);
}
}
}
return 0;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。