"异步非阻塞模型" 我觉得还OK!

网友投稿 332 2022-09-11


"异步非阻塞模型" 我觉得还OK!

常言道:“温故而知新,可以为师矣”。工作中经常会听到有的同学说“这个我知道!但是我忘了具体咋回事了,我得google查一下”。知识应该在自己脑子中形成一个体系的,有时候我们不能太过依赖google。今天就为大家分享一篇基础知识"网络IO同步与异步、阻塞与非阻塞"的精彩总结,带大家一起来温故知新。

前言

在网络编程中,阻塞、非阻塞、同步、异步经常被提到。同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?

数据流向

对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个就是系统内核(kernel)。当一个read操作发生时,它会经历两个阶段:

等待数据准备 (Waiting for the data to be ready) 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)

记住这两点很重要,因为这些IO Model的区别就是在两个阶段上各有不同的情况。

详细过程如下图:

网络IO模型详细分析

常见的IO模型有阻塞、非阻塞、IO多路复用,异步。

以一个生动形象的例子来说明这四个概念:周末我和姑娘逛街,中午饿了,我们准备去吃饭。周末人多,吃饭需要排队,我和姑娘有以下几种方案:

1

阻塞

我和姑娘点完餐后,不知道什么时候能做好,只好坐在餐厅里面等,直到做好,然后吃完才离开。姑娘本想还和我一起逛街的,但是不知道饭能什么时候做好,只好和我一起在餐厅等,而不能去逛街,直到吃完饭才能去逛街,中间等待做饭的时间浪费掉了。这就是典型的阻塞。

网络中IO阻塞如下图所示:

2

非阻塞

姑娘不甘心白白在这等,又想去逛商场,又担心饭好了。所以我们逛一会,回来询问服务员饭好了没有,来来回回好多次,饭都还没吃都快累死了啦。这就是非阻塞。需要不断的询问,是否准备好了。

网络IO非阻塞如下图所示:

3

多路复用

与第二个方案差不多,餐厅安装了电子屏幕用来显示点餐的状态,这样我和姑娘逛街一会,回来就不用去询问服务员了,直接看电子屏幕就可以了。这样每个人的餐是否好了,都直接看电子屏幕就可以了,这就是典型的IO多路复用,如select、poll、epoll。

网络IO具体模型如下图所示:

4

异步

姑娘不想逛街,又嫌餐厅太吵了,想好好休息一下。于是我们叫外卖,打个电话点餐,然后我和姑娘可以在家好好休息一下(此处忽略带姑娘回家的细节),饭好了送货员送到家里来。这就是典型的异步,只需要打个电话说一下,然后可以做自己的事情,饭好了就送来了。

linux提供了AIO库函数实现异步,但是用的很少。目前有很多开源的异步IO库,例如libevent、libev、libuv。

异步过程如下图所示:

同步与异步

实际上同步与异步是针对应用程序与内核的交互而言的。同步过程中进程触发IO操作并等待或者轮询的去查看IO操作是否完成。异步过程中进程触发IO操作以后,直接返回,做自己的事情,IO交给内核来处理,完成后内核通知进程IO完成。

同步与异步如下图所示:

阻塞与非阻塞

简单理解为需要做一件事能不能立即得到返回应答,如果不能立即获得返回,需要等待,那就阻塞了,否则就可以理解为非阻塞。

总结

通过下面的图片,可以发现非阻塞IO和异步IO的区别还是很明显的:

在非阻塞IO中,虽然进程大部分时间都不会被block,但是它仍然要求进程去主动的检查,并且当数据准备完成以后,也需要进程主动的再次调用recvfrom来将数据拷贝到用户内存。 而异步IO则完全不同。它就像是用户进程将整个IO操作交给了他人(kernel)完成,然后他人做完后发信号通知。在此期间,用户进程不需要去检查IO操作的状态,也不需要主动的去拷贝数据。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:k8s中负载均衡器【ingress-nginx】部署(k8s负载均衡保持session)
下一篇:SpringBoot拦截器使用精讲
相关文章

 发表评论

暂时没有评论,来抢沙发吧~