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

相关推荐
AA陈超2 小时前
ASC学习笔记0017:返回此能力系统组件的所有属性列表
c++·笔记·学习·ue5·虚幻引擎
人工智能训练3 小时前
Ubuntu中如何进入root用户
linux·运维·服务器·人工智能·ubuntu·ai编程·root
tianshiyeben3 小时前
WGCLOUD监控系统使用指南 - 告警消息整理完整版
linux·运维·服务器·系统安全·zabbix
Unlyrical3 小时前
splice, io_uring_prep_splice 调用(无效参数)
linux·服务器·c++·unix
---学无止境---4 小时前
Linux内核用户身份管理全链路深度剖析:setuid系统调用完整架构
linux
Lucis__4 小时前
STL设计模式探秘:容器适配器&仿函数
c++·容器·stl·仿函数
CS_浮鱼4 小时前
【Linux】进程控制
linux·运维·网络
无敌最俊朗@4 小时前
C++ 对象布局之padding(填充字节)
开发语言·c++
Miraitowa_cheems4 小时前
LeetCode算法日记 - Day 104: 通配符匹配
linux·数据结构·算法·leetcode·深度优先·动态规划