同步,异步,阻塞和非阻塞的理解

怎样理解阻塞非阻塞与同步异步的区别

Posted by xiaoh on May 31, 2016

在软件架构过程中经常会遇到数据的同步异步问题,还会牵扯到阻塞和非阻塞的问题,这个理解上很多时候我们会将概念混为一谈,这里简单区分一下其中的不同。


概念

  • 同步是两个对象之间的关系,而阻塞是一个对象的状态。
同步,异步

访问数据的方式,同步需要主动读写数据,在读写数据的过程中还是会阻塞;异步只需要I/O操作完成的通知,并不主动读写数据,由操作系统内核完成数据的读写

  • 同步和异步关注的是消息通信机制
阻塞,非阻塞

进程/线程要访问的数据是否就绪,进程/线程是否需要等待

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

区分

  • 在处理 IO 的时候,阻塞和非阻塞都是同步 IO。
  • 只有使用了特殊的 API 才是异步 IO。


同步和异步

同步就是两种东西通过一种机制实现步调一致,异步是两种东西不必步调一致

同步调用与异步调用

所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由调用者主动等待这个调用的结果。

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

同步就是打电话:我给你说了话,我就等着你说,你不说我不知道该说啥 请求线程会等待请求结果

异步就是邮件,QQ,短信:我给了你请求,我就去干别的,你爱啥时候回啥时候回 请求线程不会等待请求结果。

同步线程与异步线程

同步线程:即两个线程步调要一致,要相互协商。两个线程的运行进度各不相同,怎么才能步调一致呢?我们直观的理解就是,快的等慢的呗!快的阻塞一下等到慢的步调一致即可。

异步线程:步调不用一致,各自按各自的步调运行,不受另一个线程的影响。

  • 同步是指两个线程的运行是相关的,其中一个线程可能要阻塞等待另外一个线程的运行
  • 异步的意思是两个线程毫无相关,自己运行自己的。
同步通信与异步通信

这里的同步和异步是指:发送方和接收方是否协调步调一致

同步通信是指:发送方和接收方通过一定机制,实现收发步调协调。如:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式

异步通信是指:发送方的发送不管接收方的接收状态,如:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。


阻塞和非阻塞

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

阻塞就是这个事情阻到这儿了,不能继续往下干事了,非阻塞就是这个事情不会阻碍你继续干后面的事情。

阻塞可以是实现同步的一种手段!例如两个东西需要同步,一旦出现不同步情况,我就阻塞快的一方,使双方达到同步。


例子

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

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

你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果。

如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。

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


参考

https://www.zhihu.com/question/19732473


END