阻塞与非阻塞
概念
阻塞和非阻塞这两个概念与程序(线程)等待消息通知(无所谓同步或者异步)时的状态有关。也就是说阻塞与非阻塞主要是程序(线程)等待消息通知时的状态角度来说的。
阻塞
调用是指调用结果返回之前,当前线程会被挂起,一直处于等待消息通知,不能够执行其他业务。函数只有在得到结果之后才会返回。对于同步调用来说,很多时候当前线程可能还是激活的,只是从逻辑上当前函数没有返回而已,此时,这个线程可能也会处理其他的消息
非阻塞
指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回
虽然表面上看非阻塞的方式可以明显的提高CPU的利用率,但是也带了另外一种后果就是系统的线程切换增加。增加的CPU执行时间能不能补偿系统的切换成本需要好好评估。
同步与异步
概念
同步
:所谓同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态可以保持一致。异步
: 异步是不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠的任务序列。消息通知
: 异步的概念和同步相对。当一个同步调用发出后,调用者要一直等待返回消息(结果)通知后,才能进行后续的执行;当一个异步过程调用发出后,调用者不能立刻得到返回消息(结果)。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。
这里提到执行部件和调用者通过三种途径返回结果:状态、通知和回调。使用哪一种通知机制,依赖于执行部件的实现,除非执行部件提供多种选择,否则不受调用者控制。
阻塞与非阻塞,和同步异步无关,可以阻塞等待同步执行过程完成,也可以阻塞等待异步执行过程完成。根据以上理解, 阻塞与非阻塞/同步与异步是可以相互组合的。
同步阻塞
调用者发起IO操作请求,等待IO操作完成再返回。IO操作的过程需要等待,操作执行完成后返回结果。
同步非阻塞 调用者发起IO操作请求,询问IO操作的状态,如果未完成,则立即返回;如果完成,则返回结果。IO操作的过程需要等待执行完成才返回结果。
异步阻塞 调用者发起IO操作请求,等待IO操作完成再返回。IO操作的过程不需要等待,操作完成后通过通知或回调获得结果。
首先需要明确: 异步操作是可以被阻塞住的,只不过它不是在处理消息时阻塞,而是在等待消息通知时被阻塞。
异步非阻塞 调用者发起IO操作请求,询问IO操作的状态,如果未完成,则立即返回;如果完成,则返回结果。IO操作的过程不需要等待,操作完成后通过通知或回调获得结果。
举例
鄙人很爱看电影,于是乎就拿下载电影来说事儿吧O(∩_∩)O哈哈~
- 同步阻塞:我一直抱着ipad,盯着它的下载进度条,直到 100% 才算完成。
同步体现:等待下载完成通知;
阻塞体现在: 等待下载完成通知过程中,不能做其他任务处理。
- 同步非阻塞: 我点击下载任务后就去洗衣服(嗯,我还是很勤劳滴~),每过一段时间就去瞄一眼进度条,看到100%就算完成。
同步体现在:等待下载完成通知
非阻塞体现在:等待下载完成通知过程中,去干别的任务了,只是时不时会瞄一眼进度条。
- 异步阻塞 我换了个有下载完成通知功能的软件,下载完成就“叮”一声。不过我仍然一直等待“叮”的声音 [似不似很傻(⊙o⊙)…]。
异步体现在:下载完成“叮”一声通知;
阻塞体现在:等待下载完成“叮”一声通知 过程中,不能做其他任务处理;
- 异步非阻塞:仍然是那个会“叮”一声的下载软件,我提交下载任务后就去干别的,听到“叮”的一声就知道完成了。
异步体现在:下载完成“叮”一声通知;
非阻塞体现在:等待下载完成“叮”一声通知过程中,去干别的任务了,只需要接收“叮”声通知即可;[软件处理下载任务,我处理其他任务,不需关注进度,只需接收软件“叮”声通知,即可]