【网络IO系列】IO的五种模型,BIO、NIO、AIO、IO多路复用、 信号驱动IO

在上一篇文章中,我们了解了操作系统中内核程序和用户程序之间的区别和联系,还提到了内核空间和用户空间,当我们需要读取一条数据的时候,首先需要发请求告诉内核,我需要什么数据,等内核准备好数据之后再从内核空间拷贝到用户空间 注意加粗的部分,这两个阶段至关重要

对以上的两个过程以及操作系统的IO流程不了解的,请务必左转去看上一篇文章,上篇文章中是学习IO的基础知识,只有把上一篇文章的内容看懂了,对于后续的IO几种模型的学习和理解才会更为深刻,上一篇文章可以说是整个IO中的基石级别的知识。

文章链接 【网络IO系列】 预备知识 操作系统之内核程序和用户程序

IO的五种模型

我们回到正题,从上篇文章我们知道,当我们进行一次IO的时候,是要经过这两个阶段的,分别是

第一阶段 :等待内核准备数据

第二阶段:数据从内核空间拷贝到用户空间

这两个阶段则决定着IO的各种模型的类型,通过这两个阶段,可以将IO模型分成五种,分别是

阻塞式IO(BIO)

非阻塞式IO(NIO)

IO多路复用

信号驱动IO

全异步IO(AIO)

阻塞

说到阻塞,在这里想先明确一下,什么是阻塞。从线程或者进程的角度来看,阻塞就是因为当前执行的这个线程,暂时的失去了CPU的执行权,被挂起等待下一次线程的调度或者线程被唤醒。如果是具体到我们的IO的话,则可以理解为,阻塞的时候你需要等待,等到数据准备好或者执行结果返回,才能继续下一步的操作,不然只能一直等待下去。而非阻塞,则是,即便数据没有准备好,或者执行没有完成,你也可以去做其他的事情。

举个例子,比如说你出门排队买东西,假如你没有带手机,那你只能老老实实排队等轮到你,在这之前,你除了排队这件事之外,其他什么事情都干不了也不允许干,这个时候你就是阻塞的,因为你只能做排队这一件事。那么同样是排队,这一次你带了手机,那你排队的时候,可以边玩手机边排队,这个时候你就是非阻塞的。

接下来让我们对应到上面的两个阶段,如果等待内核准备数据的时候,执行线程可以去做其他的事,那么在第一阶段就是非阻塞的,否则就是阻塞的。如果在数据从内核空间拷贝到用户空间阶段,执行线程可以去干其他的事,那么第二阶段就是非阻塞的,否则就是阻塞的。

阻塞式IO(BIO)

阻塞式IO,是在两个阶段都阻塞的一种IO模型,用户发起IO请求,在等待数据和数据拷贝阶段,都会被阻塞,只有这两个阶段都完成了,才能去做下一阶段的事情。

就像是你没带手机去吃饭,你跟老板说要吃鱼香肉丝,然后要等老板做好菜(准备数据),然后从厨房把菜端到你面前(数据拷贝),这两个阶段你都只能等着,什么事都干不了。

由于BIO阻塞时间长,因此相对性能就会较低,所以现在用的相对也比较少了。

非阻塞IO(NIO)

非阻塞IO,可以看作是半阻塞IO,因为他在第一阶段数据准备阶段不阻塞,第二阶段数据拷贝阶段阻塞,当用户发出IO请求的时候,会有一个线程去询问内核数据准备好了吗,一直问一直问,在这期间,用户主进程可以去干其他的事,等数据准备好了,到了第二阶段,这个时候,用户线程就要执行拷贝数据,这个时候是阻塞的。这种方式的缺点就是反复的轮训去询问内核数据好了没,是很消耗CPU资源的。

就像是你带手机去吃饭,你点好菜之后,你可以一直问老板,我的菜好了没,老板说没有,问完之后就可以继续玩手机继续等,继续问。等到有一次你问,老板我的菜好了吗,老板说好了,你自己过来端一下。(注意,问菜好没有的,得是你自己问,这家NIO店的老板比较高冷,菜好了你不问他是不会主动告诉你的,这就是NIO的特点,数据准备就绪是用户线程主动发出的询问),这个时候菜好了,你要自己去端(数据拷贝),这个端菜的阶段,你期间啥都干不了,也不能玩手机,所以NIO的第二个阶段是阻塞的。

说到这里我们可以看出BIO和NIO之间的区别了,一个是傻等老板做菜给你,期间你什么都干不了,一个是自己主动询问老板,菜好了没,期间你可以玩手机,或者干其他的,相比BIO,NIO的效率就高了很多。当然,你可能会问了,为啥菜好没好,还得我自己主动去问,这也太不人性化了,确实,这个问题我们想得到,计算机的科学界大师们自然也想得到,于是为了解决这个问题,于是出现了信号驱动IO和IO多路复用。

IO多路复用

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzyzsg.html