c++简易的Epoll线程池

这是一个使用Epoll实现的简易线程池,包含服务器socket初始化、线程池资源初始化、线程池循环处理及工作线程。线程池通过条件变量和互斥锁管理任务队列,采用ET模式和Epoll_ONE_SHOT进行事件处理,确保高效并发地处理客户端连接和数据收发。
摘要由CSDN通过智能技术生成

就一个使用了Epoll的简易线程池:)

线程池头文件

Sesame_Pool.h

#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/epoll.h>
#include<error.h>
#include<mutex>
#include<thread>
#include<condition_variable>
#include<queue>
#include<vector>
#include<iostream>
#define Port 28357
#define Ip "xx.xx.xxx.xxx"
#define Thread_Num 10
//10这个是使用的线程的数量
class Sesame_Pool{

std::vector<std::thread*>Thread_Pool;//9这个是线程池
public:
Sesame_Pool(){};
int Serv_Socket;
int Serv_Epoll_fd;
void Init();//1初始化服务器socket和调用init_threadpool
void Init_Threadpool();//2仅初始化线程池资源
void Sesame_Loop();//11
std::mutex Sesame_lock;
std::condition_variable Sesame_Cv;
//4声明线程们能共享访问的锁对象和条件变量对象
std::queue<int>Task_List;//8这个是任务队列
~Sesame_Pool();
};
void Work_Thread(int Input_Socket,Sesame_Pool* Serv);//3是工作线程

Sesame_Pool.cpp

#include"Sesame_Pool.h"
void Work_Thread(int Input_Socket,Sesame_Pool* serv){
while(1){
std::unique_lock<std::mutex>Sesame_Unique_Lock(serv->Sesame_lock);
if(!serv->Task_List.empty()){
Input_Socket=serv->Task_List.front();
serv->Task_List.pop();
Sesame_Unique_Lock.unlock();//6检测任务队列并获取任务后处理任务的时候不涉及访问共享资源不需要加锁
//7下面的是业务处理 这里只写了收到什么就反射什么
if(Input_Socket==serv->Serv_Socket){
    int Cd_Socket=accept(Input_Socket,NULL,NULL);
    epoll_event Cd_Epoll_Event;
     Cd_Epoll_Event.events=EPOLLIN|EPOLLET|EPOLLONESHOT;
     Cd_Epoll_Event.data.fd=Cd_Socket;
     epoll_ctl(serv->Serv_Epoll_fd,EPOLL_CTL_ADD,Cd_Socket,&Cd_Epoll_Event);
     epoll_event Ser_Epoll_Event;
     Ser_Epoll_Event.events=EPOLLIN|EPOLLET|EPOLLONESHOT;
     Ser_Epoll_Event.data.fd=Input_Socket;
     epoll_ctl(serv->Serv_Epoll_fd,EPOLL_CTL_MOD,Input_Socket,&Ser_Epoll_Event);
//14这里使用EPOLL_CTL_MOD来重设一模一样的事件 就是重设EpolloneShot 以方便下个线程能够操作此套接字
}else{
    char buf[1024];
while(1){//19
int n=recv(Input_Socket,buf,sizeof(char[1024]),0);
if(n>0){
send(Input_Socket,buf,sizeof(buf),0);
}else if(n==0){
 epoll_event Cd_Epoll_Event;
     Cd_Epoll_Event.events=EPOLLIN|EPOLLET|EPOLLONESHOT;
     Cd_Epoll_Event.data.fd=Input_Socket;
epoll_ctl(serv->Serv_Epoll_fd,EPOLL_CTL_DEL,Input_Socket,&Cd_Epoll_Event);
break;
//16对面断开了链接 下树
}else if(n<0){
if(errno==EAGAIN){
//17代表recv已经阻塞超时了也没收到消息 重设后交给别的线程就可以
epoll_event Cd_Epoll_Event;
     Cd_Epoll_Event.events=EPOLLIN|EPOLLET|EPOLLONESHOT;
     Cd_Epoll_Event.data.fd=Input_Socket;
     epoll_ctl(serv->Serv_Epoll_fd,EPOLL_CTL_MOD,Input_Socket,&Cd_Epoll_Event);
break;
}
}
}
}
 
}else{
    serv->Sesame_Cv.wait(Sesame_Unique_Lock);//5无任务的时候就用条件变量使得线程沉睡
}
}
}
 
void Sesame_Pool::Init(){
Serv_Socket=socket(AF_INET,SOCK_STREAM,0);
if(Serv_Socket<0){
perror("socket fail");
}
sockaddr_in In;
In.sin_family=AF_INET;
In.sin_port=htons(Port);
In.sin_addr.s_addr=htonl(INADDR_ANY);
int opt=1;
setsockopt(Serv_Socket,SOL_SOCKET,SO_REUSEADDR,(const char*)&opt,sizeof(int));
if(bind(Serv_Socket,(sockaddr*)&In,sizeof(In))<0){
perror("bind fail");
}
listen(Serv_Socket,128);
Serv_Epoll_fd=epoll_create(1);
epoll_event Serv_Epoll_Event;
Serv_Epoll_Event.events=EPOLLIN|EPOLLET|EPOLLONESHOT;//12声明epoll读事件 ET工作模式 以及Epolloneshot
Serv_Epoll_Event.data.fd=Serv_Socket;
epoll_ctl(Serv_Epoll_fd,EPOLL_CTL_ADD,Serv_Socket,&Serv_Epoll_Event);
Init_Threadpool();
}
void Sesame_Pool::Init_Threadpool(){
    std::thread* th;
    for(int i=0;i<Thread_Num;i++){
     th=new std::thread(Work_Thread,0,this);
     Thread_Pool.push_back(th);
    }
}
void Sesame_Pool::Sesame_Loop(){
while(1){
    epoll_event* Epoll_Wait_Events;
int res=epoll_wait(Serv_Epoll_fd,Epoll_Wait_Events,128,0);
if(res>0){
for(int i=0;i<res;i++){
Task_List.push(Epoll_Wait_Events[i].data.fd);
Sesame_Cv.notify_one();//13有任务就入队列 并唤醒一个线程来处理
}
}
}
}
 
Sesame_Pool::~Sesame_Pool(){
   for(int i=0;i<Thread_Pool.size();i++){
       delete Thread_Pool[i];
   }//18释放堆资源
    
}

调用线程池类

#include"Sesame_Pool.cpp"
int main(){
    Sesame_Pool Test_Pool;
    Test_Pool.Init();
    Test_Pool.Sesame_Loop();
}

就酱

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值