Linux中poll和select有什么区别

来源:网站建设作者:宋琮安头衔:草根站长
导读:本期聚焦于小伙伴创作的《Linux中poll和select有什么区别》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Linux中poll和select有什么区别》有用,将其分享出去将是对创作者最好的鼓励。

在Linux系统的IO多路复用编程中,select和poll都是用于监控多个文件描述符是否就绪的经典机制,两者都能实现单进程处理多个IO事件的需求,但在设计细节和适用场景上存在明显差异。

Linux中poll和select有什么区别

基本工作机制差异

select的工作核心是维护一个固定大小的位图数组来存储需要监控的文件描述符,这个数组的大小在编译时由FD_SETSIZE决定,默认通常是1024,意味着默认情况下select最多只能同时监控1024个文件描述符。调用select时,需要将整个位图从用户空间拷贝到内核空间,内核遍历位图检查每个描述符的就绪状态,之后再把修改后的位图拷贝回用户空间,用户还需要再次遍历位图找到就绪的描述符。

poll则使用动态数组存储需要监控的文件描述符,数组的每个元素是一个pollfd结构体,结构体中包含要监控的描述符、关注的事件以及返回的事件。poll没有默认的文件描述符数量限制,只要系统内存足够就可以监控更多的描述符。调用poll时,同样需要将整个结构体数组拷贝到内核空间,内核检查后修改每个元素的返回事件字段,再拷贝回用户空间,用户遍历数组即可找到就绪的描述符。

使用方式对比

select的使用示例

下面是select监控标准输入是否可读的简单示例:

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

int main() {
    fd_set read_fds;
    struct timeval timeout;
    int ret;

    // 清空描述符集合
    FD_ZERO(&read_fds);
    // 把标准输入(文件描述符0)加入监控集合
    FD_SET(0, &read_fds);

    // 设置超时时间为5秒
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;

    // 调用select,最大描述符+1,只监控读事件,不监控写和异常事件,设置超时
    ret = select(1, &read_fds, NULL, NULL, &timeout);
    if (ret < 0) {
        perror("select error");
        return 1;
    } else if (ret == 0) {
        printf("timeout, no data inputn");
    } else {
        // 检查标准输入是否就绪
        if (FD_ISSET(0, &read_fds)) {
            printf("stdin is ready for readingn");
        }
    }
    return 0;
}

poll的使用示例

下面是poll实现相同功能的示例:

#include <stdio.h>
#include <poll.h>
#include <unistd.h>

int main() {
    struct pollfd fds[1];
    int ret;

    // 配置要监控的描述符,监控读事件
    fds[0].fd = 0; // 标准输入
    fds[0].events = POLLIN;
    fds[0].revents = 0;

    // 调用poll,监控1个描述符,超时时间5000毫秒(5秒)
    ret = poll(fds, 1, 5000);
    if (ret < 0) {
        perror("poll error");
        return 1;
    } else if (ret == 0) {
        printf("timeout, no data inputn");
    } else {
        // 检查返回的事件是否包含读就绪
        if (fds[0].revents & POLLIN) {
            printf("stdin is ready for readingn");
        }
    }
    return 0;
}

性能与适用场景差异

当监控的文件描述符数量较少时,select和poll的性能差异不大,但随着监控的描述符数量增加,两者的性能都会下降,不过poll的下降幅度相对更平缓,因为select每次都需要处理固定大小的位图,即使只监控少量描述符,也需要拷贝整个位图;而poll的数组大小只和实际需要监控的描述符数量相关。

另外select的位图需要每次调用前重新设置,因为内核会修改位图内容,而poll的结构体数组中,只有revents字段会被内核修改,events字段不需要每次重新设置,使用上更方便一些。

如果监控的描述符数量远小于1024,且需要兼容更老的系统,select是可选的方案;如果需要监控更多的描述符,或者希望使用更灵活的事件配置方式,poll会更合适。不过在更高性能的场景下,epoll通常是比两者更好的选择。

核心差异总结

对比维度selectpoll
文件描述符数量限制默认1024,由FD_SETSIZE决定无默认限制,受系统内存限制
数据结构固定大小位图动态pollfd结构体数组
参数重置要求每次调用前需要重新设置位图只需要重置revents字段,events可复用
事件类型支持读、写、异常三类事件支持更丰富的事件类型,如POLLIN、POLLOUT、POLLERR等
兼容性几乎所有系统都支持大部分类Unix系统支持,兼容性略弱于select

pollselectLinuxIO多路复用修改时间:2026-06-27 16:54:27

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