epoll是实现IO多路转接的另一种方式。它与select,poll的作用相同,都是一次等待多个文件描述符。但是,它在接口的使用及原理上与前两者有很大的不同。它改进了select和poll的缺点,使IO操作效率更高。因此它被公认为LInux2.6下性能最好的IO多路转接就绪通知方法。
下面具体介绍epoll的相关概念。
epoll
与select,poll不同的是,epoll在使用上有三个相关的系统调用。
1. epoll_create
函数原型
#include <sys/epoll.h>
int epoll_create(int size);
该函数的功能是创建一个epoll模型,然后返回一个epoll句柄(相当于文件描述符)。
参数size的作用是告诉内核关心的文件描述符数目有多大。但是从Liunx2.6.8之后,size参数是被忽略的。所以,这里不进行讨论。
该函数在调用时,会创建一个struct eventpoll结构体。在该结构体中有两个成员比较重要:

除了创建上述结构体,还会创建一个回调机制。回调机制的作用是当内核中有数据来时(满足就绪条件时),通知操作系统,这样,操作系统就不用再遍历等待满足就绪条件的文件描述符。
总结一下,在该函数内部实现以下功能(这些结构如何使用,后续进行说明):
(1)建立回调映射机制
(2)创建一棵空的红黑树;
(3)创建一个空的就绪队列;
2. 注册函数epoll_ctl
函数原型
#include <sys/epoll.h>
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
参数说明:
epfd:上述epoll模型的句柄
op:表示采取的操作,该变量的取值有如下几种:
EPOLL_CTL_ADD:将fd注册到epoll模型中
EPOLL_CTL_MOD:修改已经注册到epoll模型的的事件类型
EPOLL_CTL_DEL:删除已经注册到epoll模型中的fd。
fd:对哪个文件描述符进行上述操作
event:表示监听的文件描述符fd上的相关事件信息。该结构体定义如下:
struct epoll_event {
__uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
第一个成员变量表示事件类型,该变量与poll中的events和revents的含义类似。取值都是一个宏,不同的宏表示不同的事件类型,常见的宏为:EPOLLIN(读事件),EPOLLOUT(写事件),EPOLLET(将EPOLL设置为边缘触发,具体使用后面再详细说明)。
第二个成员变量为一枚举类型变量,结构定义如下:
typedef union epoll_data {
void *ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
} epoll_data_t;
因为是枚举类型,所以每次在使用时都只能取其中的一个成员变量。fd表示关心的文件描述符,用于存放一个int类型的数据。后两个变量分别用于存放32和64位的数据,具体存放什么数据在实际使用的时候在具体讨论。ptr为一指针,可以接受任意类型的数据,如果关心的文件描述符上的事件除了需要存放fd外,还需要存放其他的变量,此时就可以使用该变量(具体使用后面说明)。
该函数用于注

epoll是Linux系统中的一种高效IO多路转接机制,相较于select和poll,它在性能上有显著优势。epoll通过epoll_create、epoll_ctl和epoll_wait三个系统调用来实现IO事件的注册、管理和等待。epoll模型利用红黑树存储文件描述符和事件,使用回调机制在事件就绪时通知操作系统,并创建就绪队列以提高效率。epoll支持水平触发和边缘触发两种工作模式,边缘触发具有更高的性能,但需要配合非阻塞IO使用。epoll适用于高并发连接,特别是当连接数大且部分连接活跃时,但对连接数较少的情况效率较低。
最低0.47元/天 解锁文章
4776

被折叠的 条评论
为什么被折叠?



