文章目录[隐藏]
在IT领域对于同步、异步、阻塞、非阻塞是很多人理解不好的几个概念。
本文试图从最简单的角度去解读他们之间的关系,下面开门见山说明他们的关系。
本质上并没有关系
- 同步与异步是关于指令执行顺序的。
- 阻塞非阻塞是关于线程与进程的。
- 两者本身并没有必然的关联系。
他们产生关系的领域CPU中断与IO
没有IO操作,所有的代码基本都是同步的
有了IO操作后,如果没有多进程多线程,所有代码还是同步的
有了IO操作,有了多进程多线程,代码才有了异步的可能性,同时也产生了阻塞与非阻塞
同步与异步
同步是指代码调用IO操作时,必须等待IO操作完成才返回的调用方式。
异步是指代码调用IO操作时,不必等IO操作完成就返回的调用方式。
同步是最原始的调用方式。
异步则需要多线程,多CPU或者非阻塞IO的支持。
阻塞与非阻塞
阻塞是指调用线程或者进程被操作系统挂起。
非阻塞是指调用线程或者进程不会被操作系统挂起。
异步,同步与 IO,线程,进程,阻塞,非阻塞等的关系
单线程
只有同步,等待IO(Programmed I/O)。
IO都是阻塞的。
多线程(多进程)让非阻塞成为可能
- 默认同步,IO调用仍可以是阻塞的。
- 异步在多线程中成为可能。IO也可以多路复用,从而对IO进行异步调用可以不产生阻塞。
而最常用的异步调用是源于异步IO。
阻塞与非阻塞
- 同步IO必定是阻塞IO。
因为同步要求IO处理是线性的,所以当IO调用时必定会阻塞进程或者线程。 - 异步IO也一定就是非阻塞IO。
异步在代码上的处理
对于异步,在不同的语言在实现上的处理是不同的。
最基本的形式回调函数
对异步影响最原始的处理方式是回调函数,这种方式基本上可以认为是汇编语言就开始采用的方式。
因为汇编语言对中断的影响本身就是一种回调函数,而中断本身就是一种IO操作。
后来的很多编译语言都是基于回调函数形式的。包括C,C++等
其它对回调的改进 (yield => promise => async/await)
异步调用出现后,会导致代码的执行不再那么直观。
不同的语言针对异步调用引入不少代码同步化的机制。
最常用的机制就是promise , yield, async/await,事件通知
ruby是较早引入yield的语言。
javascript是使用promise被使用的最多语言
async/await源于.net
目前来看最完备的同步化解决方案是async/await 机制
阻塞与非阻塞
- 同步代码调用的是同步IO,也就是阻塞IO。(理论上也存在非阻塞IO的可能,但实际上似乎并没有)
- 异步代码不一定调用的是异步IO,也可以是同步的IO。所以异步调用不阻塞自己的线程,但是不表示IO线程一定是不阻塞的。因为异步调用的形式并不直接与IO关联,中间还有OS与编程语言参与。所以有异步调用时我们并不能确定调用与IO之间的关系。
同步、异步和IO+代码
- 同步异步分IO与代码两种。
- 在IO上同步IO等于阻塞IO,异步IO等于非阻塞IO
- 在代码上同步代码等同于调用同步IO,等同于调用阻塞IO;但并不表示异步代码一定有异步IO调用,从而也无法确定是不是一定是非阻塞IO。
总结
文章的分析了异步,同步,阻塞,非阻塞,单进程,多进程,同步代码,异步代码的同步化等的概念与关系。
由于他们之间的关系是比较复杂的,未来也存着的技术革新带来的可能性。
希望这篇文章能帮助你更好的去理解他们,并在实际过程中灵活准确的应用。
也欢迎反馈文章中的错误。
本文地址: https://www.xiongge.club/biancheng/%e7%b3%bb%e7%bb%9f/735.html
转载请注明:熊哥club → 同步,异步,阻塞,非阻塞等关系的理解
©熊哥club,本站推荐使用的主机:阿里云,CDN建议使用七牛云。
关注微信公众号『熊哥club』
免费提供IT技术指导交流
关注博主不迷路~