美文网首页
IO多路复用

IO多路复用

作者: 吃掉夏天的怪物 | 来源:发表于2021-05-25 11:45 被阅读0次

IO多路复用是一种同步IO模型,实现一个线程可以监视多个文件句柄;
一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;没有文件句柄就绪时会阻塞应用程序,交出cpu。

没有IO多路复⽤机制时,有(同步阻塞)BIO、(同步⾮阻塞)NIO两种实现⽅式,但有⼀些问题

Select 模型

每次调用select,都需要把fd_set 集合从⽤户态拷贝到内核态,如果fd有事件发生,由内核根据IO状态修改fd_set的内容,由此来通知执⾏了select()的进程哪⼀Socket或⽂件可读。

优点:

用户可以在⼀个线程内同时处理多个socket的IO请求。用户可以注册多个socket,然后不断地调用
select读取被激活的socket,即可达到在同⼀个线程内同时处理多个IO请求的目的。而在同步阻塞
模型中,必须通过多线程的方式才能达到这个目的。
缺点:

  1. 每次调⽤select,都需要把 fd_set 集合从用户态拷贝到内核态,如果 fd_set 集合很大时,那这个
    开销也很⼤
  2. 同时每次调⽤select都需要在内核遍历传递进来的所有 fd_set ,如果 fd_set 集合很大时,那这个
    开销也很⼤
  3. 为了减少数据拷贝带来的性能损坏,内核对被监控的 fd_set 集合⼤⼩做了限制,并且这个是通过
    宏控制的,⼤小不可改变(限制为1024)

Poll 模型

poll的机制与select类似,与select在本质上没有多⼤差别,管理多个描述符也是进⾏轮询,根据描述符
的状态进⾏处理,但是poll没有最⼤⽂件描述符数量的限制。也就是说,poll只解决了上⾯的问题3,并
没有解决问题1,2的性能开销问题。

EPOLL模型

我们在调用epoll_create时,内核除了帮我们在epoll文件系统里建了个file结点,在内核cache里建了个
红黑树用于存储以后epoll_ctl传来的socket,还会再建立⼀个rdllist双向链表,用于存储准备就绪的事
件,当epoll_wait调⽤时,仅仅观察这个rdllist双向链表⾥有没有数据即可。
有数据就返回,没有数据就
sleep,等到timeout时间到后即使链表没数据也返回。所以,epoll_wait⾮常⾼效。

Epoll的触发模式:

LT(水平触发)模式下,只要这个文件描述符还有数据可读,每次 epoll_wait都会返回它的事件,
提醒用户程序去操作;
ET(边缘触发)模式下,在它检测到有 I/O 事件时,通过 epoll_wait 调⽤会得到有事件通知的文件
描述符,对于每⼀个被通知的⽂件描述符,如可读,则必须将该⽂件描述符⼀直读到空,让 errno
返回 EAGAIN 为止,否则下次的 epoll_wait 不会返回余下的数据,会丢掉事件。如果ET模式不是非
阻塞的,那这个⼀直读或⼀直写势必会在最后⼀次阻塞。

为什么会有ET触发模式?

如果采用LT模式的话,系统中⼀旦有大量你不需要读写的就绪文件描述符,它们每次调用epoll_wait都会
返回,这样会大大降低处理程序检索自己关心的就绪文件描述符的效率。而采用ET这种边缘触发模式的
话,当被监控的⽂件描述符上有可读写事件发⽣时,epoll_wait()会通知处理程序去读写。如果这次没有
把数据全部读写完(如读写缓冲区太⼩),那么下次调⽤epoll_wait()时,它不会通知你,直到该文件描述
符上出现第⼆次可读写事件才会通知你,这种模式比⽔平触发效率⾼,系统不会充斥⼤量你不关心的就
绪⽂件描述符。

epoll_create: 函数创建⼀个epoll句柄,参数size表明内核要监听的描述符数量。调⽤成功时返回⼀
个epoll句柄描述符,失败时返回-1。
epoll_ctl: 函数注册要监听的事件类型。四个参数解释如下:
epfd: 表示epoll句柄
op: 表示fd操作类型,有如下3种
 EPOLL_CTL_ADD 注册新的fd到epfd中
 EPOLL_CTL_MOD 修改已注册的fd的监听事件
 EPOLL_CTL_DEL 从epfd中删除⼀个fd
 fd: 是要监听的描述符
event: 表示要监听的事件

select,poll,epoll都是IO多路复⽤的机制。I/O多路复⽤就通过⼀种机制,可以监视多个描述符,⼀旦
某个描述符就绪(⼀般是读就绪或者写就绪),能够通知程序进⾏相应的读写操作。但select,poll,
epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后⾃⼰负责进⾏读写,也就是说这个读写过
程是阻塞的,而异步I/O则⽆需⾃⼰负责进⾏读写,异步I/O的实现会负责把数据从内核拷贝到用户空
间。

相关文章

网友评论

      本文标题:IO多路复用

      本文链接:https://www.haomeiwen.com/subject/howxsltx.html