基础一、IO的同步、异步、阻塞、非阻塞四个概念

一、文章的目的

弄清楚四个概念,可以和别人交流的时候能够用一个概念准确的表述想要表达的意思。

二、概念解释

1.解释一

下边是四个概念组合成的四个概念的解释:

一般来说I/O模型可以分为:同步阻塞,同步非阻塞,异步阻塞,异步非阻塞IO

同步阻塞IO:在此种方式下,用户进程在发起一个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后,用户进程才能运行。JAVA传统的IO模型属于此种方式!

同步非阻塞IO:在此种方式下,用户进程发起一个IO操作以后边可返回做其它事情,但是用户进程需要时不时的询问IO操作是否就绪,这就要求用户进程不停的去询问,从而引入不必要的CPU资源浪费。其中目前JAVA的NIO就属于同步非阻塞IO。

异步阻塞IO:此种方式下是指应用发起一个IO操作以后,不等待内核IO操作的完成,等内核完成IO操作以后会通知应用程序,这其实就是同步和异步最关键的区别,同步必须等待或者主动的去询问IO是否完成,那么为什么说是阻塞的呢?因为此时是通过select系统调用来完成的,而select函数本身的实现方式是阻塞的,而采用select函数有个好处就是它可以同时监听多个文件句柄,从而提高系统的并发性!

异步非阻塞IO:在此种模式下,用户进程只需要发起一个IO操作然后立即返回,等IO操作真正的完成以后,应用程序会得到IO操作完成的通知,此时用户进程只需要对数据进行处理就好了,不需要进行实际的IO读写操作,因为真正的IO读取或者写入操作已经由内核完成了。目前Java中还没有支持此种IO模型。   

文字截取博客链接:https://xmuzyq.iteye.com/blog/783218

2.解释二

“阻塞”与"非阻塞"与"同步"与“异步"不能简单的从字面理解,提供一个从分布式系统角度的回答。

1).同步与异步

同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)

所谓同步,就是在发出一个*调用*时,在没有得到结果之前,该*调用*就不返回。但是一旦调用返回,就得到返回值了。

换句话说,就是由*调用者*主动等待这个*调用*的结果。

而异步则是相反,*调用*在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在*调用*发出后,*被调用者*通过状态、通知来通知调用者,或通过回调函数处理这个调用。

典型的异步编程模型比如Node.js

举个通俗的例子:

你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。

而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。

2). 阻塞与非阻塞

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.

阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。

非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

还是上面的例子,

你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。

在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。

文字截取内容链接:https://www.zhihu.com/question/19732473/answer/20851256

三、总结和理解

我很同意第二中的第2条解释的。现在我想用第二种解释的内容重新表达一下第一种解释中的四个组合概念。

首先要回顾一下:同步和异步说的是消息通讯机制;阻塞和非阻塞说的是看线程调用返回时的状态。

解释一的重新解释:

同步阻塞IO:用户进程在发起一个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后,用户进程才能运行。

IO操作重新解释:操作主体发起调用(或者叫命令、指令)以后,和调用同层的逻辑会暂时“停止”,需要等到同层逻辑的调用返回之后,主体才会向下执行。

同步是说:操作主体发起调用之后,主体知道调用的返回值是强依赖调用返回的结果的,在没有获得调用返回结果的话,主体是不会在向下有动作的。换句话说,主体知道发起的调用所引起的操作最终的返回值,是需要通过调用返回来获得到,并且在获得返回前是不会有其他的行为的。

阻塞是说调用返回前,主体所在的进程是暂停的,也就是阻塞的。

同步非阻塞IO:在此种方式下,用户进程发起一个IO操作以后边可返回做其它事情,但是用户进程需要时不时的询问IO操作是否就绪,这就要求用户进程不停的去询问,从而引入不必要的CPU资源浪费。其中目前JAVA的NIO就属于同步非阻塞IO。

同步是说:操作主体发起调用之后,然后不停的去询问调用是否已经返回确定结果,直到调用的返回值是确定的结果,在没有获得调用返回结果的之前,主体是不会在执行依赖调用返回值确定结果的逻辑的。

非阻塞是说调用返回前,主体所在的进程可以做其他的事情,和“暂停”相比较的另外一种叫法就是非阻塞。

异步阻塞IO:此种方式下是指应用发起一个IO操作以后,不等待内核IO操作的完成,等内核完成IO操作以后会通知应用程序,这其实就是同步和异步最关键的区别,同步必须等待或者主动的去询问IO是否完成,那么为什么说是阻塞的呢?因为此时是通过select系统调用来完成的,而select函数本身的实现方式是阻塞的,而采用select函数有个好处就是它可以同时监听多个文件句柄,从而提高系统的并发性!

异步是说:操作主体发起调用之后,主体不会再去管调用返回的确定结果,而是select系统来监控调用返回的确定结果的,得到之后select系统就会通知主体或者其他的主体去完成依赖调用确定结果的逻辑。

阻塞:这种方式的阻塞和前两种所说的阻塞说的不是一个地方,如果硬要说阻塞的话,那只能是select系统有进程在监听调用返回的确定结果是阻塞的。

异步非阻塞IO:在此种模式下,用户进程只需要发起一个IO操作然后立即返回,等IO操作真正的完成以后,应用程序会得到IO操作完成的通知,此时用户进程只需要对数据进行处理就好了,不需要进行实际的IO读写操作,因为真正的IO读取或者写入操作已经由内核完成了。目前Java中还没有支持此种IO模型。

异步是说:操作主体发起调用之后,主体不会再去管调用返回的确定结果,而是处理调用之后返回的确定结果的另外一个主体通知发起调用的主体或者其他的主体去完成依赖调用确定结果的逻辑。

非阻塞:这种方式的非阻塞硬要说,和第一种和第二种同一个地方的话,确实是异步,因为发起调用之后,主体的进程是不会管调用返回的确定结果的,所以根本就不用“暂停”。

四、总结

所以第二种理解是比较准确地。两组定义一个是说信息通讯机制的,一个是说的是进程状态的。要根据分析问题的场景组合或者不组合才能更好的理解问题。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值