导读:本期聚焦于小伙伴创作的《C++中的I/O多路复用是什么?select、poll和epoll原理与使用详解》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++中的I/O多路复用是什么?select、poll和epoll原理与使用详解》有用,将其分享出去将是对创作者最好的鼓励。

在C++网络编程里,I/O多路复用是指利用操作系统提供的机制,让一个进程或线程可以同时监视多个套接字或其他文件描述符,一旦其中某些描述符就绪(可读、可写或出现异常),就通知程序进行处理,从而避免为每个连接创建一个线程带来的资源消耗。

C++中的I/O多路复用是什么?select、poll和epoll原理与使用详解

什么是I/O多路复用

传统的阻塞式I/O模型中,调用recv或accept时线程会一直等待,直到数据到达。当并发连接变多,线程数量暴涨,上下文切换成本很高。I/O多路复用把“等待多个描述符就绪”这件事交给内核,程序只需要在内核通知后,对已经就绪的描述符做非阻塞读写。

常见的三种实现

  • select:出现最早,跨平台支持好
  • poll:解决了select的部分限制
  • epoll:Linux下高性能方案

select原理与使用

select通过三个fd_set位图分别监听读、写和异常事件,每次调用都需要把集合从用户态拷贝到内核态,内核遍历所有描述符,返回后用户也要遍历来找出就绪的描述符。

#include <sys/select.h>
#include <unistd.h>
#include <iostream>

int main() {
    fd_set readfds;
    FD_ZERO(&readfds);
    int listen_fd = 3; // 假设监听套接字为3
    FD_SET(listen_fd, &readfds);
    // 设置超时时间
    struct timeval tv;
    tv.tv_sec = 5;
    tv.tv_usec = 0;
    // 调用select,最大描述符+1
    int ret = select(listen_fd + 1, &readfds, NULL, NULL, &tv);
    if (ret > 0) {
        if (FD_ISSET(listen_fd, &readfds)) {
            std::cout << "listen_fd可读,有新连接" << std::endl;
        }
    }
    return 0;
}

poll原理与使用

poll使用pollfd结构体数组代替select的位图,没有描述符数量硬限制,但每次调用仍要遍历全部描述符,随着监控数量增加,效率会下降。

#include <poll.h>
#include <iostream>

int main() {
    struct pollfd fds[1];
    fds[0].fd = 3;        // 监听套接字
    fds[0].events = POLLIN; // 关注可读事件
    fds[0].revents = 0;
    int ret = poll(fds, 1, 5000); // 超时5秒
    if (ret > 0) {
        if (fds[0].revents & POLLIN) {
            std::cout << "描述符可读" << std::endl;
        }
    }
    return 0;
}

epoll原理与使用

epoll是Linux特有的机制,内核使用红黑树管理监听的描述符,并用就绪链表记录就绪事件。程序通过epoll_wait只取回已经就绪的描述符,不需要遍历全部监控项,非常适合海量连接。

#include <sys/epoll.h>
#include <iostream>

int main() {
    int epfd = epoll_create1(0);
    struct epoll_event ev, events[10];
    ev.events = EPOLLIN;
    ev.data.fd = 3; // 监听套接字
    epoll_ctl(epfd, EPOLL_CTL_ADD, 3, &ev);
    int n = epoll_wait(epfd, events, 10, 5000);
    for (int i = 0; i < n; i++) {
        if (events[i].data.fd == 3) {
            std::cout << "有新连接或数据到达" << std::endl;
        }
    }
    return 0;
}

三者对比

机制描述符上限效率特点平台
select有限(如1024)每次全量拷贝和遍历跨平台
poll无硬限制仍全量遍历跨平台
epoll系统限制只返回就绪项Linux

使用建议

在编写C++网络程序时,如果目标环境是Linux且需要支撑高并发,优先使用epoll;如果需要可移植性且连接数不多,select或poll更简单。无论使用哪种方式,都应将套接字设为非阻塞模式,配合多路复用避免线程卡死。

C++_I/O多路复用selectpollepoll网络编程修改时间:2026-07-25 12:54:25

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。