Linux系统IO多路复用总结

IO复用的三种方法

1. select :

select会将所有监听的文件描述符拷贝到内核中挂起进程。当某个描述符可读或者可写的时候,中断程序唤起进程,select将监听的文件描述符再次拷贝到用户空间,然后select遍历这些文件找到IO可用的文件。下次监控的时候需要再次拷贝这些文件描述符到内核空间。select支持监听的最大描述符数量为1024.
在这里插入图片描述

select 的缺点:

  1. 每次调用select时,都要将fd集合从用户态拷贝到内核态,这个开销在fd很多时会较大
  2. 每次调用时都需要在内核态遍历传递进来的所有fd,这个开销在fd很多时也很大
  3. select支持的文件描述符数量太少,为1024

2. poll

poll 使用链表来保存文件描述符,其他与select相同。

3. Epoll

epoll将文件描述符拷贝到内核空间后使用红黑树进行维护,同时向内核注册每个文件描述符的回调函数,当某个文件描述符可读可写的时候,将这个文件描述符加入到就绪链表里,并唤起进程,返回就绪链表到用户空间。
在这里插入图片描述

epoll提供了三个函数,分别为epoll_create,epoll_ctl和epoll_wait函数,其中epoll_create函数用来创建一个epoll句柄,epoll_ctl用来 注册要监听的事件的类型,epoll_wait用来等待事件的产生。

Epoll对select缺点的改进

  1. 对于select每次都要将文件句柄拷贝到内核空间这一问题。epoll的解决方案在epoll_ctl函数中,每次注册新的事件到epoll句柄中时,会将所有的fd拷贝进内核,而不是在epoll_wait时重复拷贝,epoll保证每个句柄在整个过程中只拷贝一次
  2. 对于缺点2,即每次调用时都要在内核态遍历所有传进来的fd。

​ epoll选择不像select或者poll一样每次都把current轮流加入fd对应的设备等待队列中,而只在epoll_ctl时挂一遍,并且为每个fd指定一个回调函数,当设备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数,这个回调函数会把就绪的fd加入一个就绪链表。epoll_wait实际上就是在这个就绪链表中查看有没有就绪的fd,利用schedule_timeout()函数实现睡一会,判断一会的效果。

  1. epoll没有对句柄数量的限制,一般的数量和操作系统内存的大小相关。它所支持的FD上限是可以打开的文件的数目。这个数目一般大于2048,具体数目可以cat /proc/sys/fs/file-max察看。

总结

  1. epoll相对于select和poll的性能提升主要在回调函数。poll和select需要不断轮询所有的fd集合,直到设备就绪,每次轮询时都需要遍历所有的fd。而epoll由于回调函数的存在,每次都只需要判断就绪队列中是否存在fd即可,省去多次遍历,从而提高性能。
  2. select和poll在每次调用时都需要把fd集合从用户态拷贝到内核态,并且都要将current往设备队列中挂一次。而epoll只需要一次拷贝,并且只需要挂一次即可,从而节省开销。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值