高级IO——五种IO模型

IO可以分为同步IO和异步IO,在同步IO中又包括阻塞IO、非阻塞IO、信号驱动IO和IO多路转接。

为了更好地理解这些IO模型,了解它们的区别,我们在这里可以简单的举一个例子来辅助理解:相信在日常生活中,我们很多人都有过钓鱼的经历。钓鱼是一件考验耐心和毅力的活动,假设有一天,在一条宽广的河边,有很多人在钓鱼。其中小一采用的钓鱼方法是将鱼饵挂到鱼钩上抛至河中后,就目不转睛的看着鱼竿,等着鱼上钩;小二相比较小一就显得聪明了很多,他将鱼钩抛到河中后,就拿出一本书开始看,过一会观察一次鱼竿的动静;小三是个很善于动脑筋的人,他觉得小二的做法好虽好,但是定期的查看会使他不能专心的干一件事,所以他就想出了一个办法:他在鱼竿尾部挂了一个小铃铛,当铃铛响时就说明鱼上钩了,收竿即可,铃铛没响时就代表没有鱼上钩,那么他就不必查看鱼竿的动静,专心干自己的事情即可;小四是一个卖鱼的人,他觉得前三个人这样一条一条的钓太浪费时间,所以他在河岸边放置了多条鱼竿,当哪条鱼竿动了,就收哪只竿;小五是一个大老板,他觉得这条河里钓上来的鱼异常鲜美,但是他业务繁忙,所以他干脆把装备给了自己的司机,让司机替自己去钓鱼,当钓完鱼后给他打电话即可。

在上面这个例子中,我们可以看到,不同的人对待同一件事情的处理方法不同,完成这件事情的效率也就不同。

这个例子中的小一这种钓鱼的方式就可以类比于阻塞IO;小二这种钓鱼的方式就可以类比于非阻塞IO;小三这种钓鱼的方式就可以类比于信号驱动IO;小四这种钓鱼的方式就可以类比于IO多路转接;而小五的这种钓鱼方式就可以类比于异步IO。

下面我们就这五种IO模型来进行详细的介绍。


  • 阻塞IO

阻塞IO:在内核将数据准备好之前,系统调用会一直等待。

所有的套接字,默认都是阻塞方式。

阻塞IO是最常见的IO模型。


  • 非阻塞IO

非阻塞IO:如果内核还未将数据准备好,系统调用仍然会直接返回,并且返回EWOULDBLOCK错误码。

非阻塞IO往往需要程序员以循环的方式反复尝试读写文件描述符,这个过程称为轮询。

轮询是基于非阻塞式接口的。

轮询对于CPU来说是较大的浪费,一般只有特定场景下才使用。


  • 信号驱动IO

信号驱动IO:内核将数据准备好的时候,使用SIGIO信号通知应用程序进行IO操作。


  • IO多路转接

IO多路转接:虽然从流程图上看起来和阻塞IO类似,实际上最核心在于IO多路转接能够同时等待多个文件描述符的就绪状态


  • 异步IO

异步IO:由内核在数据拷贝完成时,通知应用程序(而信号驱动是告诉应用程序何时可以开始拷贝数据)。

异步IO中,应用程序充当的是发起者和后续使用数据的角色,并未参与IO的相关细节。


  • 总结

任何IO过程中,都包含两个步骤,第一是等待,第二是数据搬迁(即拷贝)。而且在实际的应用场景中,等待消耗的时间往往都远远高于拷贝的时间。所以,让IO更高效,最核心的办法就是让等待的时间尽量少

阻塞IO与非阻塞IO的区别:等待方式不同。

同步IO与异步IO的区别:同步IO自己发起活动,自己进行数据搬迁;异步IO只需发起活动,只需最终拿到数据,不参与数据搬迁的过程。




猜你喜欢

转载自blog.csdn.net/cecilia3333/article/details/80557292
今日推荐