EPOLLONESHOT
作用:避免竞争文件描述符(这里是网络编程,那就是避免竞争套接字);
使用注意事项:仅仅监听一次事件。当监听完这次事件之后,就会把这个fd从epoll的内核事件检测的队列中删除;如果想要再次使用请使用EPOLL_CTL_MOD重新添加事件;
注意这里的移除的队列并非从内核事件中删除该事件,仅仅是从内核事件检测队列中移除,而内核事件表中任然存在该事件,对于套接字而言如果不close(该套接字),那么该套接字仍然会存在,所以记住不用了close(该套接字);close(该套接字),就从内核事件表中移除了
例子:
服务器端代码:
在这里插入代码片
```cpp
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<assert.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/epoll.h>
#include<pthread.h>
#include<iostream>
#define MAX_EVENT_NUMBER 1024//最大事件连接数
#define BUFFER_SIZE 1024//接收缓冲区大小
using namespace std;
struct fds{
//文件描述符结构体,用作传递给子线程的参数
int epollfd;
int sockfd;
};
int setnonblocking(int fd){
//设置文件描述符为非阻塞
int old_option=fcntl(fd,F_GETFL);
int new_option=old_option|O_NONBLOCK;
fcntl(fd,F_SETFL,new_option);
return old_option;
}
void addfd(int epollfd,int fd,bool oneshot){
//为文件描述符添加事件
epoll_event event;
event.data.fd=fd;
event.events=EPOLLIN|EPOLLET;
if(oneshot){
//采用EPOLLONETSHOT事件
event.events|=EPOLLONESHOT;
}
epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&event);
setnonblocking(fd);
}
void reset_oneshot(int epollfd