Linux/POSIX 多路IO复用

多路复用IO概念

如何管理 fd 的可读可写事件?

IO 多路:指同时对多个文件进行读写操作。大体有两种方案:

  1. 阻塞IO模式

    • 一个线程只能处理一个流的IO事件

    • 缺点:若线程数增多性能会变差

      多个线程处理多个IO(浪费CPU资源,效率低)—— 单个线程while循环。

while(true) {
   
    select(stream[]);
    for (i->stream[]) {
   
        if i has data {
   
            read data until unavailable
        }
    }
}
  1. 多路复用IO。复用是指:使用一个线程处理多个文件fd的读写 的模式。

    • 让每一个 fd 觉得,当前线程只在给他一个fd跑腿。

    • 要尽可能的少的空转,要把所有的时间都用在处理句柄的 IO 上。

为了实现上诉的功能,内核提供了 3 种系统调用 :selectpollepoll

系统调用

select poll epoll比较

相同:这 3 种系统调用都能够管理 fd 的可读可写事件,

  • 所有 fd 不可读不可写时,阻塞线程切走 cpu
  • 存在 fd 可读写时,唤醒对应线程。

适用场景

  • select/poll:适合连接数少、跨平台需求或兼容性要求高的场景。

    • 优先选择 poll:在多数现代场景中,poll 的灵活性(无 fd 数量限制、独立事件设置)更优。

    • 仅在特定场景用 select:如兼容性要求、极低并发且需多事件监控,或依赖剩余超时时间时。

  • 高并发场景选 epoll/kqueue:若在 Linux 下,直接使用 epoll;BSD 系用 kqueue,彻底超越 select/poll。适合 Linux 下高并发、长连接的服务器(如 Web 服务器、实时通信系统)。短连接频繁的场景可能因频繁调用 epoll_ctl 影响性能。

特性 select poll epoll
文件描述符数量限制 有(1024) 无(基于链表实现)
内核实现 基于轮询(polling),内核遍历 fd 检查状态。 基于轮询:同select 基于回调(事件驱动)
遍历效率 低(O(n) 遍历)返回后需遍历fd检查状态。 低:同select 高(O(1) 回调)
拷贝开销 开销大:每次调用都需要把fd集合从用户态拷贝到内核态。 开销大:同select 开销小:在内核中维护了一个事件表。
数据拷贝 每次复制 fd 集合 每次复制 fd 数组 内核维护事件表,无需全拷贝
可移植性 POSIX 标准,跨平台 POSIX 标准,跨平台 Linux 特有
触发模式 水平触发(LT) 水平触发(LT) 水平触发(LT)、边缘触发(ET)

水平触发(LT)、边缘触发(ET)

  • 水平触发是只要fd处于就绪状态,每次调用都会通知;
  • 边缘触发只在状态变化时通知一次,需要程序处理完所有数据,否则可能丢失事件。

epoll

简介

总而言之,epoll是

  • linux内核提供的一种系统调用,性能好于另外两个系统调用 poll,select。

  • 用于处理IO 多路复用(管理 fd 的可读可写事件)

    • 在所有 fd 不可读不可写无所事事的时候,可以阻塞线程,切走 cpu

    • fd 可读写的时候,对应线程会被唤醒

使用事件驱动的方式,当某个fd就绪时,内核会采用回调机制直接将该fd加入到就绪列表,不需要每次都扫描所有fd。epoll_wait返回时只提供就绪的事件。会把哪个流发生的什么样的IO事件进行通知,时间复杂度O(1),对流的操作都是有意义的

while(true) {
   
	active_stream[] = epoll_wait();
    for i in active_stream[] {
   
        read or write till unavailable
    }
}

epoll 的使用

使用 epoll 需要以下三个系统调用:

//头文件
#include <sys/epoll.h>

// 创建一个epoll句柄,size用来告诉内核需要监听的数目
int epoll_creat(int size);
// epoll的事件注册函数
int epoll_ctl(int epfd, int op, int fd, struct 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值