redis--IO 多路复用(select + poll)

一、IO 多路复用基础定义

文件描述符 FD:Linux 中一切皆文件,FD 是标识文件 /socket 的递增整数。 IO 多路复用:单线程监听多个 FD,当任意 FD 可读 / 可写时收到通知,避免阻塞 IO 卡死、非阻塞 IO 空转,提升 CPU 利用率。

对比:阻塞 IO 会卡死线程;非阻塞 IO 循环轮询耗 CPU;多线程方案线程开销大。多路复用就是 "一个服务员等多个顾客,谁准备好了就处理谁"。 两个阶段:①内核等待数据就绪;②内核把数据拷贝到用户空间。 三大实现:select、poll、epoll。select/poll 只告知 "有 fd 就绪",需要用户遍历查找;epoll 直接返回就绪 fd 集合。

二、select

1. 原理与结构

  • fd_set:用 bit 位图存储监听 fd,固定 1024bit,最多监听 fd 编号小于 1024 的文件描述符。bit 位 0 = 未监听 / 未就绪,1 = 就绪。
  • select 函数参数:
    • nfds:最大 fd 值 +1
    • readfds/writefds/exceptfds:读、写、异常事件集合
    • timeout:超时控制(NULL 永久阻塞,0 非阻塞,>0 限时等待)
  • 流程:
    1. 用户构造 fd_set 位图
    2. 用户态 → 内核态,拷贝整个 fd_set
    3. 内核遍历所有 fd,阻塞等待就绪
    4. 就绪后修改位图,拷贝回用户态
    5. 用户程序循环遍历位图,找出就绪 fd 执行 IO

2. select 三大缺点(高频考点)

  1. 拷贝开销大:每次调用都要把整个 fd_set 在用户、内核之间来回拷贝
  2. 需要全量遍历:只会通知有 fd 就绪,不知道是哪一个,用户态必须遍历全部 fd
  3. 上限 1024:位图固定大小,监听 fd 不能超过 1024

三、poll(select 改良版)

1. 结构

struct pollfd {int fd; short events; short revents;}

  • fd:要监听的文件描述符
  • events:感兴趣的事件(POLLIN 读、POLLOUT 写、POLLERR 错误)
  • revents:内核返回、实际触发的事件

2. 执行流程

  1. 自定义大小 pollfd 数组,放入所有待监听 fd 和关心事件
  2. 调用 poll,数组拷贝进内核,内核用链表保存(无 1024 上限)
  3. 内核遍历全部 fd,等待就绪 / 超时
  4. 就绪后把 pollfd 数组拷贝回用户空间,返回就绪 fd 数量
  5. 用户判断 n>0,遍历 pollfd 数组,看 revents 找到就绪 fd

3. 和 select 对比

✅ 改进:抛弃固定位图,用数组 + 链表,解除 1024fd 上限 ❌ 遗留问题:

  • 每次调用仍然需要全数组用户↔内核拷贝
  • 内核依旧遍历全部 fd
  • 返回后用户态仍然需要遍历数组查找就绪 fd

结论:poll 只是解决了 fd 数量限制,时间复杂度依旧 O (n),性能提升有限。

四、select vs poll 对比简表

表格

对比项 select poll
存储结构 固定 bit 位图 fd_set 动态 pollfd 数组
FD 上限 最大 1024 无硬性上限
就绪通知 位图标记,遍历查找 revents 标记,遍历查找
拷贝 每次全量拷贝位图 每次全量拷贝数组
时间复杂度 O(n) O(n)
适用场景 少量 fd 场景,老旧兼容 中少量 fd,需要超过 1024 监听
相关推荐
lzhdim5 小时前
100条常用SQL语句
数据库·sql·mysql·mybatis
天河归来5 小时前
从原始消息到业务数据:三层数据架构的设计与实践
数据库·数据仓库·架构
数据库小学妹5 小时前
金融数据库成本怎么算?五笔钱加一张TCO表
数据库·金融行业·数据库选型·国产化替代·tco·金融数据库
KaiwuDB5 小时前
KaiwuDB 分布式集群扩缩容,从原理到完整操作踩坑总结
运维·数据库·分布式
auspicious航6 小时前
PostgreSQL的备份与恢复
数据库·postgresql
这个DBA有点耶6 小时前
从 MySQL 到时序数据库:我帮朋友做迁移的完整记录
数据库·架构·dba
泡海椒6 小时前
深度解析JQuick-SQL AST到逻辑计划转换机制|分布式SQL原理
数据库·分布式·sql
心静财富之门6 小时前
Python 数据共享四种方案完整实例(同进程 / JSON / Redis / HTTP)
数据库·python·oracle
略略略咯咯6 小时前
啊啊啊啊啊
java·服务器·数据库