异步/同步,阻塞/非阻塞,单线程/多线程概念梳理
Posted fairjm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异步/同步,阻塞/非阻塞,单线程/多线程概念梳理相关的知识,希望对你有一定的参考价值。
最近看了一文说到异步是单线程的,顿时就傻眼了,对相关概念和同事进行了一些讨论和总结.
文中的描述是以我的理解来说的,可能不一定准确甚至正确,有错欢迎指正.
这三个概念我认为是描述不同的维度的,概念正交.
异步 同步
异步和同步是不同的流程设计风格.
但存在依赖关系的操作之间是同步的,也就是如果操作B依赖操作A的返回,那么B必须要在A结束后才能执行.
比如你要读取文件然后对文件内容进行处理,那么读取内容和处理内容就是同步的.
而异步这是操作间没有依赖关系,或者先后顺序并不重要.
比如用户登陆要给登陆奖励,在确认用户可登陆后之后的登陆流程和发放奖励间并无依赖关系,那么他们就可以异步执行.
这个概念主要描述依赖关系和流程设计.
阻塞 非阻塞
这个概念是描述操作是否会立即返回的.
这个概念常常和异步/同步混在一起.
同步就一定是阻塞的吗,这不一定,这取决于同步执行里的各个操作是否是阻塞的.
非阻塞操作可以被用在异步API的实现.
基于单线程的异步API实现里的操作一般都会要求为非阻塞.
单线程 多线程
这两个概念常和异步 同步混在一起.
比如认为异步一定是要多线程才能实现的,但其实不然,有很多基于Eventloop的单线程实现.
单线程 多线程主要描述的是运行的环境.
如图:
(来源参考3)
一些实现中相关的概念
在实现中,为了高效的执行这些概念会被组合起来使用.
单线程的异步操作,需要依赖非阻塞操作(不然单个线程就直接阻塞了).而这里异步的目的是为了提高线程的利用率,这在IO密集的应用中比较有效.
但如果操作本身是计算密集的,那么单线程的异步操作就没有太大的意义了.
而如果无法满足操作都是非阻塞的,那常常会使用多线程来规避主线程(例如服务器中的请求处理线程和GUI中的UI线程)阻塞.
这种一般会返回Future
等类似的占位符,并提供非阻塞查询结果是否返回,或者支持回调函数.
这在java中比较常见,毕竟java世界中的阻塞操作比较多.
上述概念和IO的关系.
一些对应的API.
要记住的是这些操作和单线程/多线程都没什么关系.
更多的内容之前有翻译一篇文章: 各个类型的IO - 阻塞, 非阻塞,多路复用和异步
对应语言的各种IO要看使用了系统提供的哪些类型的API.
例如Java,在Linux中的AIO是多线程模拟实现的,而在windows下使用了IOCP使用.
参考资料:
1.https://blog.slaks.net/2014-12-23/parallelism-async-threading-explained/
2.https://stackoverflow.com/questions/41770985/i-o-blocking-in-green-threads
以上是关于异步/同步,阻塞/非阻塞,单线程/多线程概念梳理的主要内容,如果未能解决你的问题,请参考以下文章