gpt4 book ai didi

rust - `.await` 调用何时安排在不同的线程上 - 以及 tokio 任务何时在线程之间移动

转载 作者:行者123 更新时间:2023-12-03 07:52:31 25 4
gpt4 key购买 nike

我想了解 Rust 中 tokio 的 async/await 线程模型。我特别想知道 async/await 何时会导致代码在不同线程上执行。

我观察到的是,在用 #[tokio::main] 注释的 async fn main 中运行 async/await/join 代码(这会创建一个多-线程运行时)在同一线程中执行所有代码。在我开始通过 tokio::spawn 执行代码之前,我没有看到其他线程被使用。

一些relevant docs .

Tasks are the unit of execution managed by the scheduler. Spawning thetask submits it to the Tokio scheduler, which then ensures that thetask executes when it has work to do. The spawned task may be executedon the same thread as where it was spawned, or it may execute on adifferent runtime thread. The task can also be moved between threadsafter being spawned. (emphasis mine)

这表示生成的单个 tokio 任务可以在执行期间在线程之间移动。这什么时候会发生?

还有 block_on 的文档这就是 #[tokio::main] 运行函数体的地方

This runs the given future on the current thread, blocking until it iscomplete, and yielding its resolved result. Any tasks or timers whichthe future spawns internally will be executed on the runtime.

这可以理解为除非产生新的任务或计时器,否则给定 future 的代码将全部在同一线程上运行。这是我观察到的。

异步 ​​rust 代码是否会在 .await 和 join 调用中同时(但不是并行)进行 future,并且仅在 tokio::spawn 时安排在不同的线程上使用过吗?

文档似乎另有说明,如果是这样,如何决定将执行转移到新线程?

最佳答案

I don't see additional threads being used until I start executing code via tokio::spawn.

那是因为他们不这样做, future 不是调度单位,只有任务才是。

This says that a single tokio task that is spawned can be moved between threads during its execution. When would this happen?

这需要稍微倒带一下:多线程运行时意味着 tokio 有多个调度程序,每个线程一个。每个线程都有一个本地队列,以及一个用于整个运行时的附加全局共享队列

默认情况下,如果任务是从异步代码生成的,则该任务会在当前调度程序的队列中排队。如果本地队列已满或任务是从运行时外部创建的(例如通过 Runtime::block_on),则将其添加到共享队列。

当调度程序没有任务运行时,它会检查其本地队列。

如果其本地队列为空或没有任务准备就绪,则它会尝试从同级队列窃取任务。这就是任务可以在线程之间移动的时候。

关于rust - `.await` 调用何时安排在不同的线程上 - 以及 tokio 任务何时在线程之间移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76823112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com