Linux 下网络编程:高性能 IO 多路复用,epoll 事件循环
·
// 6. 事件循环
struct epoll_event events[MAX_EVENTS];
while (true) {
// 等待事件发生
int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
if (nfds < 0) {
perror("epoll_wait failed");
break;
}
epoll 事件循环(服务器的「心脏」)
这是epoll 高并发服务器最核心的死循环,服务器99%的时间都在这里运行。
整段代码的作用(大白话)
// 开辟一个数组,用来存放【触发了事件的socket】
struct epoll_event events[MAX_EVENTS];
// 死循环:永远运行,等待客户端连接/发数据
while (true) {
// 阻塞等待:只要有事件来,就立刻返回
int nfds = epoll_wait(...);
// 出错处理
}
一句话:这是服务器的「永动心跳」,负责等待并接收所有客户端事件。
逐行深度拆解
1. 定义事件数组
struct epoll_event events[MAX_EVENTS];
作用:
创建一个「事件结果数组」
MAX_EVENTS:你自己定义的最大同时处理事件数(比如 100、1024、4096)events:epoll_wait 会把所有触发的事件填到这个数组里
类比:
这是一个**“事件托盘”**
epoll 检测到哪些 socket 有动静,就把它们放到这个托盘里给你。
2. 服务器主循环
while (true) {
作用:
无限循环
- 服务器必须 24 小时不停运行
- 处理完一批事件 → 立刻回去继续等待下一批
- 这就是服务器不退出、一直服务的原因
3. 核心函数:epoll_wait(等待事件)
int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
这是 epoll 最重要的函数!
作用:阻塞等待,直到有事件发生,然后返回事件数量。
四个参数逐行解释(必须背会)
| 参数 | 含义 | 解释 |
|---|---|---|
| epoll_fd | epoll 实例 | 你创建的监控器 |
| events | 事件数组 | 内核把触发的事件填到这里 |
| MAX_EVENTS | 最大事件数 | 一次最多返回多少个事件 |
| -1 | 超时时间 | -1 = 永久阻塞,直到有事件 |
重点:timeout = -1 是什么意思?
-
-1:永久阻塞
没有事件 → 程序休眠,不占CPU
有事件 → 立刻唤醒返回 -
>0:等待 N 毫秒超时 -
0:不等待,直接返回(轮询)
服务器一般都用 -1,高效节能。
返回值 nfds 是什么?
nfds = number of file descriptors ready
意思:本次有多少个 socket 触发了事件
例如:
nfds = 1→ 1 个客户端连接/发来了数据nfds = 5→ 5 个 socket 同时有事件
4. 错误判断
if (nfds < 0) {
perror("epoll_wait failed");
break;
}
- 成功:返回 ≥0
- 失败:返回 -1
- 常见错误:被信号中断、epoll_fd 失效
底层原理(超级通俗)
把 epoll 看作 保安室:
epoll_wait= 保安坐在椅子上等动静- 没有事件 → 保安睡觉(不占CPU)
- 有客户端连接/发消息 → 内核立刻叫醒保安
- 保安把所有事件放到
events托盘里 - 返回
nfds:告诉你来了几个事件
执行流程(一看就懂)
- 进入循环
- 调用
epoll_wait→ 阻塞休眠 - 客户端发来连接/数据
- 内核自动通知 epoll
epoll_wait醒来,返回事件数- 接下来就是遍历 events 数组处理事件
极简总结(超好记)
- events[MAX_EVENTS]:存放触发事件的托盘
- while(true):服务器永不退出
- epoll_wait:阻塞等待事件(连接/数据)
- nfds:返回有多少个socket需要处理
- timeout=-1:永久等待,节能高效
接下来要做什么?(你代码的下一段)
// 遍历所有触发的事件
for (int i = 0; i < nfds; i++) {
// 1. 如果是监听套接字 → 有新客户端连接
if (events[i].data.fd == listen_sockfd) {
// accept 接收连接
// 把新客户端加入 epoll 监控
}
// 2. 如果是普通客户端 → 有数据来了
else {
// read 读取数据
// 处理业务逻辑
}
}
这就是 epoll 服务器完整逻辑!
一句话总结
epoll_wait 是服务器的心脏,每一次跳动,都在处理客户端的连接与消息!
更多推荐




所有评论(0)