同步、异步、阻塞、非阻塞

阻塞与非阻塞

概念

阻塞和非阻塞这两个概念与程序(线程)等待消息通知(无所谓同步或者异步)时的状态有关。也就是说阻塞与非阻塞主要是程序(线程)等待消息通知时的状态角度来说的。

  • 阻塞调用是指调用结果返回之前,当前线程会被挂起,一直处于等待消息通知,不能够执行其他业务。函数只有在得到结果之后才会返回。

    对于同步调用来说,很多时候当前线程可能还是激活的,只是从逻辑上当前函数没有返回而已,此时,这个线程可能也会处理其他的消息

  • 非阻塞指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回

虽然表面上看非阻塞的方式可以明显的提高CPU的利用率,但是也带了另外一种后果就是系统的线程切换增加。增加的CPU执行时间能不能补偿系统的切换成本需要好好评估。

同步与异步

概念
  • 同步:所谓同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态可以保持一致。
  • 异步: 异步是不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠的任务序列。
  • 消息通知: 异步的概念和同步相对。当一个同步调用发出后,调用者要一直等待返回消息(结果)通知后,才能进行后续的执行;当一个异步过程调用发出后,调用者不能立刻得到返回消息(结果)。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。

这里提到执行部件和调用者通过三种途径返回结果:状态、通知和回调。使用哪一种通知机制,依赖于执行部件的实现,除非执行部件提供多种选择,否则不受调用者控制。

阻塞与非阻塞,和同步异步无关,可以阻塞等待同步执行过程完成,也可以阻塞等待异步执行过程完成。根据以上理解, 阻塞与非阻塞/同步与异步是可以相互组合的。

  • 同步阻塞

    调用者发起IO操作请求,等待IO操作完成再返回。IO操作的过程需要等待,操作执行完成后返回结果。

  • 同步非阻塞 调用者发起IO操作请求,询问IO操作的状态,如果未完成,则立即返回;如果完成,则返回结果。IO操作的过程需要等待执行完成才返回结果。

  • 异步阻塞 调用者发起IO操作请求,等待IO操作完成再返回。IO操作的过程不需要等待,操作完成后通过通知或回调获得结果。

    首先需要明确: 异步操作是可以被阻塞住的,只不过它不是在处理消息时阻塞,而是在等待消息通知时被阻塞。

  • 异步非阻塞 调用者发起IO操作请求,询问IO操作的状态,如果未完成,则立即返回;如果完成,则返回结果。IO操作的过程不需要等待,操作完成后通过通知或回调获得结果。

举例

鄙人很爱看电影,于是乎就拿下载电影来说事儿吧O(∩_∩)O哈哈~

  1. 同步阻塞:我一直抱着ipad,盯着它的下载进度条,直到 100% 才算完成。

同步体现:等待下载完成通知;

阻塞体现在: 等待下载完成通知过程中,不能做其他任务处理。

  1. 同步非阻塞: 我点击下载任务后就去洗衣服(嗯,我还是很勤劳滴~),每过一段时间就去瞄一眼进度条,看到100%就算完成。

同步体现在:等待下载完成通知

非阻塞体现在:等待下载完成通知过程中,去干别的任务了,只是时不时会瞄一眼进度条。

  1. 异步阻塞 我换了个有下载完成通知功能的软件,下载完成就“叮”一声。不过我仍然一直等待“叮”的声音 [似不似很傻(⊙o⊙)…]。

异步体现在:下载完成“叮”一声通知;

阻塞体现在:等待下载完成“叮”一声通知 过程中,不能做其他任务处理;

  1. 异步非阻塞:仍然是那个会“叮”一声的下载软件,我提交下载任务后就去干别的,听到“叮”的一声就知道完成了。

异步体现在:下载完成“叮”一声通知;

非阻塞体现在:等待下载完成“叮”一声通知过程中,去干别的任务了,只需要接收“叮”声通知即可;[软件处理下载任务,我处理其他任务,不需关注进度,只需接收软件“叮”声通知,即可]

-------------本文结束感谢您的阅读-------------