epoll是Linux下高并发IO的首选机制,select适用于跨平台简单场景。epoll通过epoll_create、epoll_ctl和epoll_wait实现高效事件驱动,支持边缘触发(ET)模式与非阻塞IO,显著提升性能;而select受限于fd数量和遍历开销,适合低并发。结合线程池与合理资源管理可充分发挥C++网络服务性能。

在C++中实现高并发IO,epoll(Linux特有)和select是常用的多路复用机制。它们允许单个线程同时监控多个文件描述符,适合处理大量并发连接,尤其在网络服务器开发中广泛应用。
select 实现高并发IO
select 是POSIX标准支持的IO多路复用机制,跨平台兼容性好,但性能有限。
使用步骤如下:
- 初始化 fd_set 集合,包含需要监听的文件描述符(如socket)
- 调用 select 函数,传入最大fd值+1 和读/写/异常集合
- select 返回后,遍历所有fd,检查是否就绪
- 对就绪的fd进行读写操作
示例代码片段:
立即学习“C++免费学习笔记(深入)”;
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(server_fd, &read_fds);
int max_fd = server_fd;
// 添加已连接的client fd
for (int fd : client_fds) {
FD_SET(fd, &read_fds);
if (fd > max_fd) max_fd = fd;
}
struct timeval timeout = {1, 0};
int activity = select(max_fd + 1, &read_fds, nullptr, nullptr, &timeout);
if (activity > 0) {
if (FD_ISSET(server_fd, &read_fds)) {
// 接受新连接
}
for (int fd : client_fds) {
if (FD_ISSET(fd, &read_fds)) {
// 处理客户端数据
}
}
}
限制:每次调用都要遍历所有fd,fd数量上限通常为1024,效率随连接数增加显著下降。
epoll 实现高性能IO
epoll 是Linux特有的高效IO多路复用机制,适用于大规模并发场景(如数万连接)。
核心接口:
- epoll_create:创建epoll实例
- epoll_ctl:注册、修改或删除监听的fd
- epoll_wait:等待事件发生,返回就绪事件列表
两种工作模式:
- LT(水平触发):只要fd可读/可写,就会持续通知
- ET(边缘触发):仅在状态变化时通知一次,需一次性处理完数据
ET模式配合非阻塞IO能减少系统调用次数,提升性能。
示例流程:
int epfd = epoll_create1(0);
struct epoll_event ev, events[MAX_EVENTS];
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = server_fd;
epoll_ctl(epfd, EPOLL_CTL_ADD, server_fd, &ev);
while (true) {
int n = epoll_wait(epfd, events, MAX_EVENTS, -1);
for (int i = 0; i < n; i++) {
if (events[i].data.fd == server_fd) {
// 接受新连接,并加入epoll
} else {
// 处理客户端数据(非阻塞读取)
handle_client(events[i].data.fd);
}
}
}
关键优化建议
- 使用非阻塞IO配合epoll ET模式,避免单个慢连接阻塞整个线程
- 合理设置事件数量和缓冲区大小,减少内存拷贝
- 结合线程池处理复杂业务逻辑,避免在IO线程中做耗时操作
- 管理好fd生命周期,及时从epoll中删除关闭的连接










