操作系统 ------ I/O多路复用

select、poll、epoll都是内核提供给用户态的多路复用系统调用,进程可以通过一个系统调用函数从内核中获取多个事件。

一、select

        select实现的方法是,将已经连接的socket放到文件描述符集合,之后调用select函数将文件按描述符集合拷贝到内核中,内核通过遍历检查是否有事件发生,socket标记为可读或可写,之后将文件描述符集合拷贝到用户态,之后用户再进行遍历找到可读或可写的socket,之后执行后续操作。

事件集合:用户通过传递3个参数来关注可读、可写、异常3类事件

最大支持文件描述符:select使用固定长度的BitsMap,表示文件描述符集合,在Linux中,由于内核中的FD_SETSIZE限制,默认最大值为1024。

二、poll

事件传递的效率和内核检测就绪效率和select是一样的。

事件集合:统一所有事件类型,只有1个参数来关注

最大支持文件描述符:链表存放事件,为最大限制(受系统最大限制)

三、epoll

epoll相较于select/poll而言,解决了内核态到用户态的拷贝问题,并且解决了通过遍历查询是否有事件发生。

具体解决:

  • epoll在内核里使用红黑树跟踪进程所有待检测的文件描述符,把需要监控的socket通过epoll_ctl()函数加入内核中的红黑树里。而select和poll在内核里并没有类似epoll红黑树这样保存所有待检测的socket的数据结构,故每次都需要传入整个socket集合给内核。所以epoll相较于select和poll而言减少了内核和用户空间大量的数据拷贝和内存分配。
  • epoll使用事件驱动的机制,内核里维护了一个链表来记录就绪事件,当socket有事件发生时,通过回调函数内核会将其加入到这个就绪事件列表中,当有用户调用epoll_wait()函数时,只会返回有事件发生的文件描述符的个数,不需要进行轮询,这样提高了检测的效率。

四、边缘触发和水平触发 

epoll支持两种触发模式:边缘触发(ET)、水平触发(LT)

边缘触发(ET):当被监控的socket描述符有可读事件发生时,服务器只会从epoll_wait()中苏醒一次

水平触发(LT):当被监控的socket描述符上有可读事件发生时,服务器会不断的从epoll_wait中苏醒,直到内核缓冲区数据被read函数读完才结束

使用水平触发模式,当内核通知完文件描述符可读时,接下来可以去继续进行检测,查看是否是刻可读或者可写。

使用边缘触发模式,I/O事件只会通知一次,而且我们并不知道到底能读多多少数据,因此会尽可能读取数据,以免错失机会。所以,边缘触发模式和非阻塞IO搭配使用,程序会一直执行I/O操作,直到系统调用返回错误。

select/poll只有水平触发,epoll默认为水平触发,但是可以进行更改。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值