多路复用概念
- I/O多路复用是通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。
- 阻塞I/O有一个比较明显的缺点是在I/O阻塞模式下,一个线程只能处理一个流的I/O事件。如果想要同时处理多个流,需要多个进程或者多个线程,但是这种方式效率不高。
- 非阻塞的I/O需要轮询查看流是否已经准备好了,比较典型的方式是忙轮询。
忙轮询
- 忙轮询方式是通过不停的把所有的流从头到尾轮询一遍,查询是否有流已经准备就绪,然后又从头开始。如果所有流都没有准备就绪,那么只会白白浪费CPU时间。
无差别的轮询方式
- 为了避免白白浪费CPU时间,我们采用另外一种轮询方式,无差别的轮询方式。即通过引进一个代理,这个代理为select/poll,这个代理可以同时观察多个流的I/O事件。当所有的流都没有准备就绪时,会把当前线程阻塞掉;当有一个或多个流的I/O事件就绪时,就从阻塞状态中醒来,然后轮询一遍所有的流,处理已经准备好的I/O事件。
- 如果I/O事件准备就绪,那么我们的程序就会阻塞在select处。我们通过select那里只是知道了有I/O事件准备好了,但不知道具体是哪几个流(可能有一个,也可能有多个),所以需要无差别的轮询所有的流,找出已经准备就绪的流。可以看到,使用select时,我们需要O(n)的时间复杂度来处理流,处理的流越多,消耗的时间也就越多。
最小轮询方式
- 无差别的轮询方式有一个缺点就是,随着监控的流越来越多,需要轮询的时间也会随之增加,效率也会随之降低。
- 所以还有另外一种轮询方式,最小轮询方式,即通过epoll方式来观察多个流,epoll只会把发生了I/O事件的流通知我们,我们对这些流的操作都是有意义的,时间复杂度降低到O(k),其中k为产生I/O事件的流个数。
select/poll/epoll都是采用I/O多路复用机制的,其中select/poll是采用无差别轮询方式,而epoll是采用最小的轮询方式。
I/O复用的优势
- I/O多路复用的优势并不是对于单个连接能处理的更快,而是在于可以在单个线程/进程中处理更多的连接。
- 与多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。
原文:https://blog.youkuaiyun.com/chewbee/article/details/78108223