一、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,表示已超时。