【多路复用器 - 3】epoll

将多路复用器用epoll_creat()、 epoll_ctl()、 epoll_wait() 三个系统函数实现,最牛逼的版本

 过程描述

上面的程序是server端

  1. server端通过epoll_creat() = fd0 创建一个负责连接的fd0
    1. fd0在用户进程只是一个地址,在内核空间开辟了一块空间用fd0表示
    2. 用户进程没有开辟空间来维护fd集合,这里就是共享内存的优化
  2. server端通过epoll_ctl(fd0...fn) 将fd0负责连接的,注册到内核空间fd0表示的这块空间中
  3. server端通过epoll_ctl(fd0...fn) 将fd1...fdn负责数据读写的,注册到内核空间中
  4. server端通过epoll_wait(timeout) 获取IO准备就绪的fd列表
  5. 如果返回结果为空,非阻塞式的循环获取,如果返回的fd集合不为空,fd集合中的所有IO都是数据已经到达的

内核怎么监听fd列表

a.当fdx的磁盘io准备就绪后通过DMA总线将磁盘数据复制到共享内存dma区,这个是异步完成

b.磁盘产生一个数据就绪的中断

c1.磁盘数据就绪中断产生一个事件

c2.该中断通知CPU处理IO事件

d.OS通过事件到中断向量表中中查找内核注册的回调函数

e.cpu执行回调函数,将就绪的fdx从内核fd0空间中取出来,然后将fdx挂在一棵红黑树上,整棵树表示fx就绪的事件,连接事件,读取数据事件


epoll_wait()不断非阻塞遍历这个棵数,将就绪fd返回给用户进程,用户进程拿到就绪的fdx,此时fdx的数据已经提前复制到了dma区,不必将数据从内核态再复制到用户态

核心总结

epoll

  1. 突破了操作系统监听fd的数量限制
  2. 避免了fd数据从用户态到内核态的复制
  3. 非阻塞式的获取就绪fd列表
  4. 非阻塞式且带有超时时间的获取就绪fd列表
  5. 获取就绪列表效率高,每次只返回就绪,且避免空调用
  6. 就绪fd事件通过红黑树管理,提高查询效率,联想一下HashMap的一个hash桶如果节点数超过8个,则将链表转换成红黑树;这里的设计类似。数据结构太强大了,无处不在!!!

整个IO的进化历史显示,IO只有阻塞和非阻塞的区分,IO都是同步的,因为read的时候还是需要复制数据;只有计算区分同步和异步线程处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值