epoll系列系统调用
epoll是Linux系统特有的I/O复用函数。不同于select,poll,epoll是通过使用一组函数完成任务,epoll把用户关心的文件描述符上的事件放在内核的一个事件表里面,所以无需每次调用都要重复传入文件描述符或事件集;
文件描述符:用来唯一描述内核中的事件集使用以下函数创建:
#include<sys/epoll.h>
int epoll_create(in size);
size只是指定了内核事件表的大小;
下面的函数用来操作epoll的内核事件集:
#include<sys/epoll.h>
int epoll_fcntl(int epfd,int op,int fd,struct epoll_event * event);
fd :要操作的文件描述符,op指定操作类型:注册,修改,删除
EPOLL_CTL_ADD,EPOLL_CTL_MOD,EPOLL_CTL_DEL
event指定事件:
epoll_event的结构体如下:
struct epoll_event
{
_uint32_t events;//epoll事件
epoll_data_t data;//用户数据
}
epoll_data_t的联合如下:
typdef union epoll_data
{
void* ptr;
int fd;
uint32_t u32;
uint64_t u64;
}epoll_data_t;
该联合体使用最多的是fd,指定事件所从属的文件描述符;ptr用来指定fd相关的用户数据,由于联合体不能同时使用参数,因此将文件描述符和事件绑定起来,只能另辟道路,例如:放弃event_data_t中的fd 而ptr指向用户数据的fd;
epoll_wait()
该函数在一段超时时间内等待一组文件描述符上的事件;
#include<sys/epoll.h>
int epoll_wait(int epfd,struct epoll_event* events,int maxevents,int timeout)
epoll_wait函数检测到事件时,就将所有就绪的事件从内核表中(由epfd参数指定)复制到events指向的数组中,这个数组只用来输出epoll_wait检测到的就绪事件,maxevents指定了最多监听事件个数。
poll和epoll的差别:
int ret = poll(fds,MAX_EVENT_NUMBER,-1);
for(int i = 0;i < MAX_EVENT_NUMBER;++i);
{
if(fds[i].revents & POLLIN)
{
int sokfd = fds[i].fd;
}
}
int ret = epoll_wait(epollfd,events,MAX_EVENT_NUMBER)
{
for(int i = 0;i< ret;i++)
{
int sockfd = events[i].data.fd;
}
}
LT模式和ET模式
epoll对文件的操作由两种模式:LT:低电平触发;ET:边沿触发
LT模式检测的事件通知应用程序后,应用程序可以不立即处理该事件,而ET则必须先处理该事件。