epoll 事件全集、每个事件的含义、哪些事件在实际服务器中最常见、哪些会组合出现

一、epoll 事件总览(最常用的 10 个)

epoll 返回的 events 是一个 bitmask(位图),可能包含多个事件组合。

下面按使用频率从高到低列出来:

事件名 含义 是否常见
EPOLLIN fd 可读(有数据到达 / 对端关闭) ★★★★★
EPOLLOUT fd 可写(发送缓冲区有空位置) ★★★★
EPOLLERR socket 出错(RST 等) ★★★★★
EPOLLHUP 对端关闭(FIN) ★★★★★
EPOLLRDHUP 半关闭(对方调用了 shutdown(SHUT_WR)) ★★★★
EPOLLET 边缘触发模式 ★★★★★(高性能服务器必须用)
EPOLLONESHOT 一次性事件,处理完需手动重置 ★★★★
EPOLLPRI 紧急数据(TCP OOB) ★★
EPOLLEXCLUSIVE 避免惊群(监听 socket 用) ★★★
EPOLLWAKEUP 系统唤醒(安卓) 少见

二、最常见 & 必须处理的事件组合

epoll 最典型的 four events:

复制代码
EPOLLIN     → 有数据可读
EPOLLOUT    → 可以写数据
EPOLLERR    → 错误,必须关闭
EPOLLHUP    → 对方挂断,必须关闭

大多数情况下会处理的就是这四个。

三、事件组合出现的情况(epoll 特点)

epoll 一次返回的 events 可能包含多个标志位,例如:

1. 正常收发数据:

复制代码
events = EPOLLIN

2. 写入数据阻塞后,现在可写:

复制代码
events = EPOLLOUT

3. 对端关闭 + 有未读完的数据:

复制代码
events = EPOLLIN | EPOLLRDHUP

4. 错误 + 可读(错误最高优先级)

复制代码
events = EPOLLIN | EPOLLERR

5. 边缘触发写法常见:

复制代码
events = EPOLLIN | EPOLLOUT | EPOLLET

四、生产服务器具体会遇到哪些组合?

实际开发中出现频率最高的组合如下:

① 客户端发送数据 → 服务器读事件:

复制代码
EPOLLIN

② 客户端断开 → 两种情况:

正常断开:

复制代码
EPOLLHUP | EPOLLIN

异常断开:

复制代码
EPOLLERR

半关闭(常见于 HTTP/1.1):

复制代码
EPOLLIN | EPOLLRDHUP

③ 写缓冲区满后又能写了:

复制代码
EPOLLOUT

④ 边缘触发(ET)+ 写事件:

复制代码
EPOLLIN | EPOLLET

⑤ epoll 已经出错:

复制代码
EPOLLERR

这种必须马上 close。

五、事件含义详细讲解

EPOLLIN(最常见)

  • 套接字可读

  • read() 不会阻塞

  • 包含:对端关闭时 read=0 也会触发 IN

EPOLLOUT

  • 套接字可写

  • send() 不会阻塞

EPOLLERR(非常关键)

  • 底层 TCP 出错(如对方 RST)

  • 必须马上关闭 fd

  • 如果不处理,会造成 CPU 100%

EPOLLHUP(非常关键)

  • 对端关闭(FIN)

  • 必须关闭 fd,不要再读写

EPOLLRDHUP(高质量服务器必须用)

  • 对端半关闭(如 shutdown)

  • HTTP keep-alive 场景很常见

  • 比 EPOLLHUP 更准确

EPOLLET:边缘触发

  • 高性能服务器必用(比如 nginx)

  • 必须一次性读完所有数据,否则不会再触发

EPOLLONESHOT:一次性事件

  • 用于多线程模型,防止多个线程抢同一个 fd

六、一个真实服务器事件判断模板

cpp 复制代码
uint32_t ev = events;

// 优先处理错误
if (ev & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) {
    closeConn(fd);
    return;
}

// 可读事件
if (ev & EPOLLIN) {
    handleRead(fd);
}

// 可写事件
if (ev & EPOLLOUT) {
    handleWrite(fd);
}

这就是 nginx、muduo、libevent 的标准写法。

相关推荐
strive programming1 小时前
Linux从入门到精通——基础IO(简洁清晰版)
linux·运维·服务器
比昨天多敲两行1 小时前
C++ 多态
开发语言·c++
是娇娇公主~1 小时前
C++ 多态机制与虚函数实现原理
c语言·c++
节点小宝1 小时前
一站式部署:支持Windows、macOS、Linux三端的统一方案
linux·运维·macos
m0_569881471 小时前
跨语言调用C++接口
开发语言·c++·算法
乌鸦9441 小时前
《库制作与原理》
linux·动态库
ZhengEnCi1 小时前
L1D-Linux系统Node.js部署Claude Code完全指南 🚀
linux·ai编程·claude
hnxaoli2 小时前
统信小程序(十一)快捷地址栏
linux·python·小程序
2501_924952692 小时前
C++中的过滤器模式
开发语言·c++·算法
zhixingheyi_tian2 小时前
gdb 之 attach
c++