epoll函数是Linux特有的IO函数,epoll使用一组函数来完成任务,其次epoll把用户关心的数据放到内核事件表中,当有就绪事件发生的时候,再将就绪事件复制到epoll_event数组中,它不像select和poll那样需要通过轮询方式来查询检测注册的文件描述符是否处于就绪状态。
函数:
一、epoll_create(int size)用于创建内核事件表
epoll_create()成功返回内核事件表的文件描述符,失败返回-1
size 参数现在并不起作用,只是给内核一个提示,告诉它事件表需要多大。
二、epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)用于操作内核事件表
epoll_ctl()成功返回 0,失败返回-1
epfd 参数指定要操作的内核事件表的文件描述符
fd 参数指定要操作的文件描述符
op 参数指定操作类型:
EPOLL_CTL_ADD 往内核事件表中注册 fd 上的事件
EPOLL_CTL_MOD 修改 fd 上的注册事件
EPOLL_CTL_DEL 删除 fd 上的注册事件
event 参数指定事件,它是 epoll_event 结构指针类型
三、epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)用于在一段超时时间内等待一组文件描述符上的事件
epoll_wait()成功返回就绪的文件描述符的个数,失败返回-1,超时返回 0
epfd 参数指定要操作的内核事件表的文件描述符
events 参数是一个用户数组,这个数组仅仅在 epoll_wait 返回时保存内核检测到的所有就绪事件,而不像 select 和 poll 的数组参数那样既用于传入用户注册的事件,又用于输出内核检测到的就绪事件。这就极大地提高了应用程序索引就绪文件描述符的效率。
maxevents 参数指定用户数组的大小,即指定最多监听多少个事件,它必须大于0
timeout 参数指定超时时间,单位为毫秒,如果 timeout 为 0,则 epoll_wait 会立即返回,如果 timeout 为-1,则 epoll_wait 会一直阻塞,直到有事件就绪。
下面是poll和epoll在使用上的区别:
epoll部分代码展示:
int main() {
int sockfd = InitSocket();//监听套接字
assert(sockfd != -1);
//创建内核事件表返回描述符
int epfd = epoll_create(EPOLLSIZE);
assert(epfd != -1);
struct epoll_event ev;
ev.data.fd = sockfd;
ev.events = EPOLLIN;
//将监听套接字注册到内核事件表中
if (epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev) == -1) {
printf("epoll_ctl add error\n");
exit(0);
}
while (1) {
struct epoll_event events[MAX_FD];
//检测到的就绪的事件描述符会被存到event数组中,省去了轮询查找就绪描述符的状态
int n = epoll_wait(epfd, events, MAX_FD, 2000);
if (n < 0)
{
printf("epoll_wait error\n");
continue;
} else if (n == 0) {
printf("timeout\n");
continue;
} else {
DealReadyEvent(events, n, sockfd, epfd);
}
}
}