IO多路复用三种模型的区别(鄙人的理解)

以下只是鄙人的粗略理解,有错误地方请指正!
select模型

首先根据FD数组去初始化一个bitmap,bitmap也是一个数组,固定长度为1024,bitmap的下标对应一个fd的状态。

并且每次函数调用,用户态都要将一整个bitmap拷贝到内核态,由内核态去检查状态,然后再将其拷贝回用户态。在用户态又根据轮询的方式,判断哪个fd就绪了,然后进行IO操作。 频繁地拷贝一整个bitmap,开销非常大,由是无差别地轮询查找就绪fd,o(n)时间复杂度, 效率非常低 。有连接限制,简单容易实现。

poll模型

与select模型类似,也是轮询FD是否就绪。只不过是用一个结构体数组代替了select中的FD数组和bitmap,这个结构体记录着FD,注册的事件,实际发生的事件。将这个结构体数组拷贝到内核态,由内核态去更新FD结构体的事件状态,然后又拷贝回用户态。

epoll模型

epoll_create(),epoll_ctl(),epol_wait()

linux特有的,底层采用双向链表+红黑树存储FD集合,查找的时间复杂度是常数时间复杂度,并且将轮询改为了事件通知的方式,维护FD集合的数据结构直接存储在内核态,减少了反复的拷贝,性能开销大幅度减小。

执行流程 epoll_create()首先初始化一个eventpoll结构体,这个结构体包含了FD就绪队列,基于红黑树实现的FD集合,阻塞队列。

调用epoll_ctl()维护红黑树FD的集合。增删改这些。

epol_wait()当前进程进入阻塞队列。

当有一个FD有事件发生的时候,就会将其FD插入到就绪队列中,这个插入动作实际是一个回调,并不是遍历,这是epoll的一个性能提升非常大的一个点,并且内核态会检查阻塞队列的进程,其FD集合中是否存在已经就绪的FD,这一步就是在红黑树里面查找FD,时间复杂度接近o(1)效率非常高,如果存在唤醒该线程。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zhou吗

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

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

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

打赏作者

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

抵扣说明:

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

余额充值