了解一下
Epoll 是一种高效的管理socket的模型,相对于select和poll更加高效。
数据结构
- sys/epoll.h
typedef union epoll_data { void ptr; int fd; __uint32_t u32; __uint64_t u64; } epoll_data_t; struct epoll_event { __uint32_t events; / Epoll events / epoll_data_t data; / User data variable / };
(1) epoll_data 联合体用来保存触发事件的某个文件描述符相关的数据.
(2) epoll_event 结构体的events字段是表示感兴趣的事件和被触发的事件:
EPOLLIN :表示对应的文件描述符可以读;EPOLLOUT:表示对应的文件描述符可以写;EPOLLPRI:表示对应的文件描述符有紧急的数据可读EPOLLERR:表示对应的文件描述符发生错误;EPOLLHUP:表示对应的文件描述符被挂断;EPOLLET:表示对应的文件描述符设定为edge模式
函数
*epoll_create, epoll_create1 函数
函数声明:int epoll_create(int size) 该函数生成一个epoll专用的文件描述符,其中的参数是指定生成描述符的最大范围。- epoll_ctl函数
函数声明:int epoll_ctl(int epfd, int op, int fd, struct epoll_event event) 该函数用于控制某个文件描述符上的事件,可以注册事件,修改事件,删除事件。
参数:epfd:由 epoll_create 生成的epoll专用的文件描述符; op:要进行的操作例如注册事件:EPOLL_CTL_ADD 注册、EPOLL_CTL_MOD 修改、EPOLL_CTL_DEL 删除
- epoll_wait函数 函数声明: int epoll_wait(int epfd,struct epoll_event events,int maxevents,int timeout) 该函数用于轮询I/O事件的发生; 参数: epfd: 由epoll_create 生成的epoll专用的文件描述符; epoll_event: 用于回传代处理事件的数组; maxevents: 每次能处理的事件数; timeout: 等待I/O事件发生的超时值(ms);-1永不超时,直到有事件产生才触发,0立即返回。返回发生事件数。-1有错误。
Sample:
int main(){ //声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件 struct epoll_event ev,events[20]; epfd=epoll_create(10000); //创建epoll句柄 listenfd = socket(AF_INET, SOCK_STREAM, 0); //把socket设置为非阻塞方式 setnonblocking(listenfd); bzero(&serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = INADDR_ANY; serveraddr.sin_port=htons(SERV_PORT); bind(listenfd,(struct sockaddr )&serveraddr, sizeof(serveraddr)); listen(listenfd, 255); //设置与要处理的事件相关的文件描述符 ev.data.fd=listenfd; //设置要处理的事件类型 ev.events=EPOLLIN; //注册epoll事件 epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev); for ( ; ; ) { //等待epoll事件的发生 nfds=epoll_wait(epfd,events,20,1000); //处理所发生的所有事件 for(i=0;i