加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
ftpserver.c 2.72 KB
一键复制 编辑 原始数据 按行查看 历史
SpaceX_zhao 提交于 2023-05-18 22:23 . alopex modify
#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;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化