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 的标准写法。

相关推荐
米高梅狮子3 小时前
03.网络类服务实践
linux·运维·服务器·网络·kubernetes·centos·openstack
June`3 小时前
网络编程时内核究竟做了什么???
linux·服务器·网络
REDcker3 小时前
有限状态机与状态模式详解 FSM建模Java状态模式与C++表驱动模板实践
java·c++·状态模式
basketball6164 小时前
C++ 构造函数完全指南:从入门到进阶
java·开发语言·c++
楼兰公子4 小时前
RK3588 + Linux7.0.3 网络工程调试错误速查手册
linux·网络·3588
Elnaij4 小时前
Linux系统与系统编程(9)——自设计shell与基础IO
linux·服务器
IMPYLH4 小时前
Linux 的 unexpand 命令
linux·运维·服务器·bash
想唱rap4 小时前
IO多路转接之poll
服务器·开发语言·数据库·c++
|_⊙5 小时前
Linux 文件知识 补充
linux·运维·服务器
落羽的落羽6 小时前
【算法札记】练习 | Week4
linux·服务器·数据结构·c++·人工智能·算法·动态规划