IO多路复用

1、IO多路复用出现的场景

是我们要设计一个高性能高吞吐 网络服务器,那么这个服务器要供很多客户端连接 并提供服务。

select实现原理

select 应用案例
将rset 从用户态 直接拷贝到内核态,交给内核来判断fd是否有来数据, 内核态判断效率 要比用户态高很多。如果没有数据到来的话那么会在select那阻塞。有数据来的时候内核会做两件事情:1、将有数据的rset对应fd置位(表示为这个fd有数据来了)。2、select函数会返回,就会走到下面 循环判断哪个fd被更改了(哪个fd被置位了),置位的fd我们就会将数据读出来并进行处理。

缺点

1、rset (bitmap)是有上限的最大1024
2、当一个fd被置位了(rset中的fd),需要重新给赋空值FD_ZERO(&rset);
3、用户态和内核态的切换 开销比较大。
4、当某一个rset中的fd被置位了,需要全部遍历rset中的fd判断到底哪个被置位了。

poll实现原理

poll应用案例
poll 跟select基本类似也是将fd拷贝到内核态,由内核态来判断fd是否有数据来。
但是poll 没有采用rset(bitmap),采用的是pollfd结构体所以带来了一些好处。
poll 也是阻塞函数 跟select 一样,有一个或者多个fd来数据的时候,内核就会将这个fd置位,置位的是 revents 字段 这里和select不一样,然后是poll 返回, 最后循环判断pollfd数组的revents字段是否被修改(置位),revents 被置位后也需要手动恢复成0。

poll解决select问题

1、解决了select 函数rset(bitmap) 大小限制(1024),poll这里改成了数组 
2、每一次都是置位 revents 这个字段,而不是将整个进行置位。每次只需要恢复revents就行了

epoll实现原理(新)

在这里插入图片描述
epoll 的fd(epfd结构体)是内核态和用户态共享的(mmap),这里和select、 poll 不太一样,这样就没有内核态和用户态的切换的资源消耗 以及拷贝的开销,判断哪个fd过来数据也是内核态判断的, 有数据过来时:1、 置位 变相置位法 ,重排 将有数据的fd放入到最前面的位置 2、 返回 跟select 和poll不一样,epoll 是有返回值的,这个返回值就是一共有多少个fd触发了事件(被置位了 / 来数据了)。

解决问题

1、解决了内核态和用户态来回切换的资源消耗 以及拷贝的开销,因为epoll的fd是用户态和内核态共享的。
4、判断哪个fd过来数据了,这个复杂度是O(1), 因为返回值就是fd被置位的数量

epoll应用案例: redis、 nginx、 java NIO

小白还在成长中… 如有不对的地方还请多多指教

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值