多路复用I/O模型的理解

什么是I/O:

不管是文件还是管道、套接字都可以被看作标准的文件描述符或者流,我们针对文件描述符的读和写操作(输入输出)就是I/O (input/ouput)。

多路复用:

指多个文件描述符的I/O的操作可以在同一个线程内顺序交替完成,复用的是同一个线程。

I/O的阻塞:

说起阻塞和非阻塞,就要提一下同步和异步,同步和异步是在一个进程或者线程的角度(或者更宏观的调用周期)看待请求和结果的时间问题,一次请求直到同一线程将需要的数据返回就是同步,否则就是请求后立马返回部分结果,最终结果被其它线程处理,通知的方式告知想要的结果。异步的进程间通信的方式有很多种,比如管道,队列,套接字,信号,共享内存等。

阻塞, 指线程在处理一个流时,需要等待一个新的I/O事件的发生而处于一种挂起状态,该状态下的线程无法继续工作,直到内核对该流产生一个新的I/O事件。阻塞模型下要想处理更多的任务,就需要创建新的进程或者线程,不过这种方式非常的低效。

非阻塞,在一个线程中,可以打开多个文件描述符,而且一旦一个流需要等待I/O事件时,不会导致整个线程的挂起,这些流被放到一个队列中,会被不断的轮询,每次轮询找出有新的I/O事件产生的流。

非阻塞轮询:

上面讲到的非阻塞模型中,内核会不断的轮询所有的流,即使任何流都没有I/O事件发生也会轮询一遍,这个样子就会非常浪费资源。为了更高效的处理非阻塞的情况,引入了更好的处理方式select和epoll

select:

该模型的产生让非阻塞有了一个比较理性的轮询方式,线程中所有的流如果没有I/O事件都会被select接管,有任何的流产生I/O事件的时候,select都会知道再去轮询,不用再去空轮询了。不过select这个时候并不知道具体哪个流上产生事件了,所以需要针对所有的流都轮询一次。时间复杂度O(n),也就是说随着要处理的流的增加,处理时间变长,效率降低。select一个线程中能打开的文件描述符的个数通常限制为1024(系统参数,可配置)

epoll:

针对select无差别轮询的问题,epoll有了更好的处理方式,epoll在所有的流上都注册有回调函数,一旦有I/O事件的产生就会触发回调,接下来就只需要处理这些已知发生I/O事件的流就可以了。而且epoll没有文件描述符打开的数量限制。

 

参考:

https://www.cnblogs.com/ajianbeyourself/p/5859989.html

 

 



“多路复用I/O模型的理解”的2个回复

发表评论

电子邮件地址不会被公开。