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

相关推荐
yyy的学习记录5 分钟前
Ubuntu下urdf模型转换成proto模型
linux·运维·ubuntu
礼拜天没时间.10 分钟前
自定义镜像制作——从Dockerfile到镜像
linux·docker·容器·centos·bash
xixingzhe210 分钟前
ubuntu安装gitlab
linux·ubuntu·gitlab
cpp_250111 分钟前
P8448 [LSOT-1] 暴龙的土豆
数据结构·c++·算法·题解·洛谷
强风79418 分钟前
Linux-传输层协议TCP
linux·网络·tcp/ip
MSTcheng.21 分钟前
【C++】C++智能指针
开发语言·c++·智能指针
云深处@26 分钟前
【C++11】部分特性
开发语言·c++
独望漫天星辰30 分钟前
C++ 树结构进阶:从工程化实现到 STL 底层与性能优化
开发语言·c++
HellowAmy34 分钟前
我的C++规范 - 鸡蛋工厂
开发语言·c++·代码规范
looking_for__39 分钟前
【Linux】应用层自定义协议与序列化
linux·服务器·网络