epoll
是 Linux 下用于处理大量文件描述符(比如网络连接)的高效 I/O 事件通知机制。它是 select
和 poll
的替代品,特别适合在需要处理大量并发连接的场景中使用,如高性能的网络服务器。
#include <sys/epoll.h>
#include <unistd.h>
// 创建一个 epoll 实例
int epoll_fd = epoll_create1(0);
if (epoll_fd == -1) {
// 错误处理
}
// 准备一个 epoll 事件结构体
struct epoll_event event;
event.events = EPOLLIN; // 关注可读事件
event.data.fd = socket_fd; // 要监听的文件描述符,比如一个 socket
// 将事件添加到 epoll 实例中
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, socket_fd, &event) == -1) {
// 错误处理
}
// 等待事件发生
struct epoll_event events[MAX_EVENTS];
int num_events = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); // -1 表示无限等待
if (num_events == -1) {
// 错误处理
}
// 处理发生的事件
for (int i = 0; i < num_events; i++) {
if (events[i].events & EPOLLIN) {
// 可读事件处理
}
// 其他事件处理...
}
// 关闭 epoll 实例
close(epoll_fd);
epoll
使用红黑树和就绪队列来管理文件描述符,使得添加、删除和查找操作的时间复杂度都是 O(1),而 select
和 poll
的时间复杂度是 O(n)。epoll
没有最大文件描述符数量的限制,而 select
和 poll
受到 FD_SETSIZE 的限制。epoll
采用事件驱动的方式,只有当文件描述符就绪时才会通知应用程序,避免了 select
和 poll
的轮询开销。EPOLLRDHUP
:表示对端套接字关闭连接,或者关闭写操作的情况。EPOLLEXCLUSIVE
:用于设置独占模式,同一时刻只有一个进程能接收事件。EPOLLONESHOT
:只监听一次事件,事件发生后需要再次注册。EPOLLET
:设置边缘触发(Edge Triggered)模式,只告诉应用程序哪些文件描述符刚刚变为就绪状态。epoll
时,需要注意处理 EINTR
错误,即系统调用被信号中断的情况。epoll_wait
的超时时间,以平衡响应性和 CPU 使用率。领取专属 10元无门槛券
手把手带您无忧上云