为什么 Javascript 的阻塞函数比 Python 少很多

Why does Javascript have much fewer blocking functions than Python

从 Javascript 移动到 Python,看着 asyncio 让我有点困惑。

作为对并发基本概念不熟悉的人,我只是假设对 Javascript 并发有肤浅的了解。

在Javascript中使用async / await的基本理解:

如果我们 运行 在 async 函数中进行任何处理,并且 await 函数的响应,我们实际上是在等待函数在 Promise.

完全合理 - 当 Promise 被赋予一个值时,我们还可以使用 .then() 等回调来处理响应。或者,只需 await.

无论这里异步的底层实现是什么(例如所有进程 运行 都在一个带有事件循环的线程上),我们如何与它交互是否重要?

现在,我搬到 Python 开始玩 asyncio。我们有 Futures,就像 Promises。突然间,我不能使用我的标准库,比如request.get(...),但我需要在库中使用非阻塞网络请求,比如aiohttp.

这里的阻塞/非阻塞是什么意思?我假设这意味着事件循环所在的单个线程被阻塞了,所以我们不能并行处理其他函数。

那么我的两个问题是:

Go 等语言的 goroutines 又如何呢?这只是一种情况,因为它是一种从一开始就内置并发性的新语言,所以阻塞函数的概念不存在。或者在 Go 中它不是单线程,所以一切都可以内在地并行化?

谢谢:)

事件循环

Javascript 和 python 的异步 io 使用基于 event loops.

的并发模型

(注意复数,因为你可以有多个事件循环来处理不同类型的任务,例如磁盘 io、网络 io、ipc、并行计算等)

事件循环的一般概念是,你有很多事情要做,所以你把这些事情os放在一个队列中,每隔一段时间(就像每个 nanosecond),事件循环从队列中选择一个事件,运行发送它一小会儿(可能是一毫秒左右),如果它还没有完成则将其推回队列,或者等到它把控制权交还给事件循环。


现在回答你的一些问题:

What does blocking / non-blocking mean here? I assume it means the single thread that the event loop is on is blocked, so we cant process other functions in parallel.

阻塞事件循环

当事件循环正在 运行 执行任务时发生事件循环阻塞,并且任务未完成或将控制权交还给事件循环,时间长于事件loop 已将其安排到 运行.

在 python 的请求库中,他们使用了一个不考虑事件循环的同步 http 库;因此,运行在循环中执行这样的任务将使其他正在耐心等待 运行 的任务饿死,直到请求完成。

Why are most functions non-blocking in Javascript, but not in Python (i.e we don't need specific libraries such as aiohttp).

JS

Javascript中的所有内容都可以阻塞事件循环。不阻塞事件循环的唯一方法是通过 setTimeout 大量使用回调。然而,如果不小心,即使 ose 回调可以阻塞事件循环,如果它们 运行o 长而不通过另一个 setTimeout 调用将控制权交还给事件循环。

(如果您从未使用过 setTimeout,但在 JS 中使用过 promises 和异步网络请求,那么您可能正在使用这样的库。Most 浏览器中使用的流行网络库(ajax、axios、fetch 等)基于流行的 XMLHttpRequest API,它提供异步网络 IO。)

Python

在python中,情况略有不同:在asyncio之前,没有“事件循环”这样的东西。在 python 解释器继续下一件事之前,一切都必须 运行 完成。这是 python 非常容易学习的部分原因(我敢说,创建...)。其原因以 python GIL 的形式出现,简单来说,它对任何 python 程序强制执行单一顺序。我鼓励您单击 link,并阅读 GIL 存在的原因。

And what about languages like Go with their goroutines?

注意:我不是围棋程序员,但是我看了something

Go 有何不同?

go 处理 goroutine 的方式与 python asyncio/js 执行事件循环的方式之间的唯一区别是 go 更多地使用 os 线程来确保线程被调度公平地充分利用他们 运行 使用的机器。

虽然 js callbacks/asyncio 任务通常 运行 在与事件循环相同的线程中,但 goroutines 能够 运行 在单独的 OS 线程和多个内核上,从而赋予它们更高的可用性和更高的并行性。 (在那种情况下,我们可以 almost 认为 goroutines 比 OS 线程更接近 OS 线程,就它们实际到达 运行,与受事件循环线程 运行s 时间限制的绿色线程相比。)