目录
1.传统阻塞I/O模型
传统的I/O阻塞模型中的“阻塞”的含义是指当前线程的阻塞性,下面用一图来说明这一阻塞I/O模型(读操作)。
看图中易知:整个I/O请求过程中用户线程是阻塞的,所以cpu的利用率大打折扣。
改进版本:上述过程中能否使得用户线程不是阻塞的呢?当然可以,见下图:
上述版本可以认为是同步的非阻塞的I/O版本,但是用户线程还是一直处于读的忙碌的过程中,无法抽出身进行其他事务。
现在提出新的需求,能否使得上述改进版本中的用户线程解放出来,使得用户线程可以去进行其他任务,当然是可以的,I/O多路复用模型解决了这个问题。
2.非阻塞I/O多路复用模型
I/O多路复用模型必须使用系统提供的select函数来监控当前读写状态,通过select函数的监控能力+reactor设计模式便可以实现非阻塞I/O多路复用模型,这样用户线程真正得到解放。如图所示:
从图中可以看出,用户线程只需要先进行事件注册以及读请求就可以完成一次读事件,用户线程不阻塞并且可以去做其他任务。监控I/O的任务交给reactor完成,reactor需要不断轮询直到数据被准备好,最后还要通知用户线程现在数据可读,希望用户线程触发读操作读入数据。综上所述,I/O多路复用模型较传统轮询式非阻塞I/O模型将轮询任务转嫁给reactor从而实现用户线程的解放。
3.I/O多路复用模型的应用
最后说下I/O复用模型常见的使用场景。redis就是采取的I/O多路复用模型,我们知道redis的读写速度极快,研究表明速度可达100000QPS,这样的高速使得redis在单线程工作下依然能够取得优越的性能,那么redis是如何解决I/O读写时用户主线程的轮询或者阻塞问题呢(如第一点所述)?没错,redis就是使用了I/O多路复用模型,解放了主线程,使得redis仅在主线程这一个线程中依靠其高读写速度实现了对客户端多个请求的处理。