扩展------IO多路复用(select,poll,epoll)

用户态和内核态

 

我们无论是从磁盘中读数据还是从网络(网卡)中读数据,都是用户态发起系统调用进入内核态,内核态中等待数据从磁盘/网卡中拷贝过来,然后再将数据拷贝回用户态,完成数据读取

其中影响到数据读取性能主要是:①内核态数据等待  ②用户态和内核态之间数据的拷贝

为什么有IO多路复用?

现在有以下5种IO模式: 

 阻塞IO(BIO):用户进程发起系统调用,要去阻塞等待数据就绪,数据就绪之后还要阻塞等待数据拷贝读取数据

非阻塞IO:用户进程发起系统调用,如果内核中没数据,就不会等待然后会直接返回一个错误信息。然后他会一直去调用一直去看数据是否就绪(会导致CPU空转)。但是如果有数据之后,进行数据拷贝返回数据时还是会阻塞。

因为阻塞IO的两次阻塞等待,以及非阻塞IO不断发起系统调用导致的CPU空转,使得IO操作效率很慢,所以IO多路复用横空出世

IO多路复用

IO多路复用:核心思想是通过一个线程去监视多个连接(FD),一旦某个连接就绪(触发读写事件),就去通知对应的应用程序去处理该连接。减少用户态和内核态之间的切换,先去判断哪个FD就绪再recvfrom去调用获得数据

IO多路复用有多种实现方式:select poll epoll。差异在于select和poll只会通知用户进程有FD就绪,但是具体是哪个就需要用户进程遍历来确认。而epoll在通知用于进程FD就绪的同时,把已就绪的FD写入用户空间。

Select模式

Poll模式

Epoll模式

每一个FD都有Callback回调,每当就绪就直接其添加到list列表中。Epoll_wait阻塞等待检查就绪列表,有就绪的列表元素就返回结果拷贝到空数组

epoll模式下的EL模式和LT模式:

三种模式比较

①在select模式中和poll模式中每次调用都需要把要监听的FD全都拷贝到内核,然后内核处理完还要全部拷贝到用户空间。而在epoll模式中,只需要通过epoll_ctl方法把要监听的FD拷贝到内核放到红黑树中,不需要每次调用再把重复的FD再放进来,只放一次就可以了。减少了拷贝的次数,数量

②在select模式中和poll模式中每次都要把所有的FD都拷贝回用户空间,然后让其去遍历寻找就绪的FD。而在epoll中就只需要通过epoll_wait监听链表,如果有数据就拷贝已经就绪的FD即可。

③select模式中因为使用的是数组最多监听1024个FD,poll虽然采用了链表,理论上无上限,但是当链表长度非常长,你遍历的时候则会花费大量时间。而在epoll模式中,FD是放在红黑树中,数量肯定是可以存很多,但是遍历(增删改查)红黑树的时间复杂度不会随着数量的增多而增加,都是O(log n)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值