IO复用——epoll系列系统调用

1、内核事件表

    epoll是Linux特有的I/O复用函数。epoll把用户关心的文件描述上的事件放在内核里的一个事件表中,并用一个额外的文件描述符来标识该内核事件表。这个额外文件描述符使用函数epoll_create函数来创建。

#include<sys/epoll.h>
int epoll_create(int size)

    size参数给内核提示事件表需要多大。该函数返回的文件描述符用作其他epoll函数的第一个参数,标识要访问的内核事件表。

2、epoll_ctl函数

    此函数用来操作内核事件表,操作类型有三种:

  • EPOLL_CTL_ADD     往事件表中注册事件
  • EPOLL_CTL_MOD    修改注册事件
  • EPOLL_CTL_DEL       删除注册事件
#include<sys/epoll.h>
int epoll_ctl(int epfd, int op, int fd, struct epoll_event* event)  //成功返回0,失败返回-1并置errno

    fd参数是要操作的文件描述符,op参数指定操作类型,event参数指定事件,epoll_event定义如下:

struct epoll_event
{
    _uint32_t events;    //epoll事件 
    epoll_data_t data;   //用户数据
};

    其中events成员描述事件类型,data成员用于存储用户数据,epoll_data_t定义如下:

typedef union epoll_data
{
    void* ptr;
    int fd;
    uint32_t u32;
    uint64_t u64;
}epoll_data_t;

    此为一个共用体,使用最多的是fd,它标识事件所从属的目标文件描述符。ptr成员可用来指定与fd相关的用户数据。

3、epoll_wait函数

    此函数为epoll系列主要系统调用函数,它在一段超时时间内等待一组文件描述符上的事件。

#include<sys/epoll.h>
int epoll_wait(int epfd, stuct epoll_event* events, int maxevents,int timeout)

    此函数成功返回时返回就绪文件描述符的个数,失败返回-1并置errno。

    timeout参数指定超时时间,maxevents参数指定最多监听多少个事件,必须大于0。epfd指定内核事件表,函数成功返回时,events参数指向一个数组,数组用于输出就绪事件,数组的大小就是函数返回的就绪文件描述符个数。

//索引epoll返回的就绪文件描述符
int ret = epll_wait(epllfd, events, MAX_EVENT_NUMBER, -1);
for(int i = 0; i < ret; i++)
{
	int sockfd = events[i].data.fd;
	/*sockfd是已经就绪的文件描述符,直接处理*/
}

4、LT和ET模式

    epoll对文件描述符的操作有两种模式:LT模式和ET模式。LT为默认模式,当往epoll内核事件表中注册一个文件描述符上的EPOLLET事件时,epoll将按照ET模式来操作该文件描述符。

    LT模式和ET模式区别:对于LT模式,epoll_wait检测到其上有事件发生并将此事件通知应用程序后,应用程序可以不立即处理该事件,当应用程序下次调用epoll_wait时,该就绪事件还会被通告到应用程序,直到事件被处理。而对于ET工作模式,当epoll_wait检测到事件发生时通知应用程序,应用程序必须立即处理,因为后面epoll_wait不会再通告此事件发生。这样ET模式比LT模式减少了同一个epoll事件被重复触发的次数,效率较高。

原文地址:https://www.cnblogs.com/fangyan5218/p/10618257.html