一、epoll_event
epoll_event 结构体用于在 Linux 中管理异步 I/O 事件。让我们来详细了解一下:
定义:
epoll_event结构体指定了内核在相应的文件描述符就绪时应保存并返回的数据。- 它的定义如下:
#include <sys/epoll.h>
struct epoll_event {uint32_t events; // Epoll 事件epoll_data_t data; // 用户数据变量
};
组成部分:
events:一个位掩码,表示与文件描述符相关联的事件。这些事件可以包括读就绪、写就绪、错误条件等。data:一个名为epoll_data的联合体,包含与事件相关的附加信息。它可以是以下之一:void* ptr:指向用户定义数据的指针。int fd:与事件相关联的文件描述符。uint32_t u32:32 位无符号整数。uint64_t u64:64 位无符号整数。
用法:
- 当文件描述符上发生事件(例如,有数据可读取)时,内核会填充一个
epoll_event结构体,其中包含相关信息。 - 应用程序使用
epoll_wait系统调用等待事件并检索相关的数据。
二、epoll_ctl
epoll_ctl 函数用于向文件描述符 epfd 引用的 epoll 实例执行控制操作。具体而言:
epoll_ctl的作用是在监听事件时告诉内核要进行何种类型的操作(添加、修改或删除)。- 它不同于
select(),后者在监听事件时告诉内核要监听哪些类型的事件,而epoll_ctl则先注册要监听的事件类型。
以下是 epoll_ctl 函数的参数说明:
epfd:为epoll文件描述符。op:表示动作,使用三个宏来表示:EPOLL_CTL_ADD:将新的文件描述符注册到epfd中。EPOLL_CTL_MOD:修改已经注册的文件描述符的监听事件。EPOLL_CTL_DEL:从epfd中删除一个文件描述符。
fd:需要监听的文件描述符。event:告诉内核需要监听的事件,其结构如第一条。
events 可以是以下几个宏的集合:
EPOLLIN:表示对应的文件描述符可以读取(包括对端 SOCKET 正常关闭)。EPOLLOUT:表示对应的文件描述符可以写入。EPOLLPRI:表示对应的文件描述符有紧急的数据可读(例如带外数据到来)。EPOLLERR:表示对应的文件描述符发生错误。EPOLLHUP:表示对应的文件描述符被挂断。EPOLLET:将EPOLL设为边缘触发(Edge Triggered)模式,相对于水平触发(Level Triggered)。EPOLLONESHOT:只监听一次事件,监听完后需要再次将该文件描述符加入到EPOLL队列中。
三、epoll_create
epoll_create 函数用于在 Linux 中创建一个 epoll 实例。让我们详细了解一下:
定义:
epoll_create创建一个新的epoll实例。- 参数
size表示这个实例需要监听的文件描述符的最大数量。从 Linux 2.6.8 开始,size参数将被忽略,但必须大于零。 epoll_create返回一个引用新epoll实例的文件描述符。这个文件描述符将用于后续所有对epoll的调用接口。
用法:
- 在创建
epoll实例后,可以使用epoll_ctl向其添加、修改或删除要监听的文件描述符。 - 使用
epoll_wait等待事件并获取准备就绪的文件描述符。
优势:
epoll是为解决 Linux 内核处理大量文件描述符而提出的方案。- 它属于 Linux 下多路 I/O 复用接口中
select和poll的增强版本。 - 特别适用于高并发服务型程序,尤其是在大量并发连接中只有少部分连接处于活跃状态的情况。
最大链接数
epoll支持的最大链接数取决于进程最大可打开的文件数目,通常远大于 1024。
四、epoll_wait
epoll_wait 是 Linux 下的一个函数,用于等待事件的发生。它是 epoll 接口的一部分,用于高效地处理大量文件描述符的 I/O 事件。
以下是 epoll_wait 函数的详细描述:
定义:
epoll_wait用于等待在epoll文件描述符epfd上的 I/O 事件。- 参数
events用来从内核获取事件的集合。 - 参数
maxevents告知内核这个events集合有多大,但不能大于创建epoll_create时的size。 - 参数
timeout是超时时间(以毫秒为单位)。如果设置为 0,函数会立即返回;如果小于 0,将会永久阻塞。
返回值:
epoll_wait返回需要处理的事件数目。如果返回 0,表示已超时。