I/O操作和多路复用select、poll、epoll机制的对比

四个I/O概念(阻塞、非阻塞、同步、异步)

① 阻塞:调用函数。函数没有接收完数据或没有得到结果前,就不会返回。(调用结果返回之前,当前线程会被挂起,进入非可执行状态)
例:Linux中默认所有的socket都是阻塞的。
当用户进程调用了 read()/recvfrom() 等系统调用函数,首先会进入内核空间中。当这个网络I/O没有数据的时候,内核就要等待数据的到来。而在用户进程这边,整个进程会被阻塞,直到内核空间返回数据。
当内核空间的数据准备好了,它就会将数据从内核空间中拷贝到用户空间,此时用户进程才解除阻塞的的状态,重新运行起来。
所以,阻塞I/O的特点就是在IO执行的两个阶段(用户空间与内核空间)都被阻塞了。

② 非阻塞:调用函数,函数立即返回
特点:用户进程需要不断的 主动询问 内核空间的数据准备好了没有。

③ 同步:就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。和阻塞相比,同步只是从逻辑上当前函数没有返回,它还会抢占CPU去执行其他逻辑,也会主动检测I/O是否准备好。

④ 异步:不需要等待内核完成实际对I/O的读写操作就直接返回了

I/O操作总结

同步IO和异步IO的区别就在于:数据拷贝的时候进程是否阻塞
阻塞IO和非阻塞IO的区别就在于:应用程序的调用是否立即返回

多路复用的对比

① 多路复用的好处:单个进程就可以同时处理多个网络连接的I/O。
② select,poll,epoll本质上都是同步I/O。因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的。
③ 异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。

select函数的缺点

① 每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
② 同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大
③ select支持的文件描述符数量太小了,默认是1024

poll函数

poll机制和select机制类似,但是没有最大文件描述符数量的限制。

epoll函数

①:在epoll_ctl函数中会把所有的fd拷贝进内核。而不是在epoll_wait的时候重复拷贝,保证了每个fd在整个过程中只会拷贝一次。
②:在epoll_ctl函数中为每个fd都指定一个回调函数,当设备就绪会唤醒等待队列中的fd并调用回调(回调的作用是把fd加入一个就绪链表中),epoll_wait只需要判断这个就绪链表中有无数据即可。无数据的时候就无需遍历,有数据了再遍历就绪链表。
③:支持的fd上限是最大可以打开文件的数目。

总结

①:表面上看epoll的性能最好,但是在连接数少并且连接都十分活跃的情况下,select和poll的性能可能比epoll好,毕竟epoll的通知机制需要很多函数回调。
②:select低效是因为每次它都需要轮询。但低效也是相对的,视情况而定,也可通过良好的设计改善

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈海平20220310

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值