多线程 tokio 是否在单个操作系统线程上运行任务?

aba*_*abo 1 rust rust-tokio

当我在 tokio 多线程运行时生成一个任务时,是否保证它会选择一个运行时操作系统线程并仅在其上运行?或者在轮询 future 时它可能会在不同的操作系统线程之间跳转?

更新:如果一项任务可以在操作系统线程之间切换,是否可以将其配置为仅使用一个线程?

Mat*_* M. 6

Tokio 中有多种工具可以处理任务到线程的映射:

  1. 运行时可以使用多个线程(默认)或单个线程。
  2. 可以生成可以在任何运行时线程上执行的任务,或者可以固定到当前运行时线程。
  3. 任务可以在正常运行时池之外的专用线程上生成。

更多详情敬请关注!

运行

Tokio 有 2 种运行时:一种是多线程运行时,它使用工作窃取来实现最佳效率;另一种是单线程运行时。

您可以使用以下命令手动选择运行时runtime::Builder

let runtime = runtime::Builder::{new_multi_thread, new_current_thread}().build()?;
Run Code Online (Sandbox Code Playgroud)

或者您可以使用属性宏main

//  Default, ie multi-threaded.
#[tokio::main]
async fn main() -> ... { ... }

//  Explicit multi-threaded, you can also configure the number of worker-threads.
#[tokio::main(flavor = "multi_thread", worker_threads = N)]
async fn main() -> ... { ... }

//  Single-threaded.
#[tokio::main(flavor = "current_thread")]
async fn main() -> ... { ... }
Run Code Online (Sandbox Code Playgroud)

任务生成

您可以根据单个任务决定在何处运行它:

  • spawn将使用当前运行时工作线程池。
  • spawn_local将使用当前线程。
  • spawn_blocking将使用专门为此任务保留的新创建的线程。

spawnspawn_blocking要求任务及其结果为Send,因为它们涉及(潜在的)线程迁移,而 whilespawn_local没有这样的要求。

任务迁移

那么,什么时候任务从一个线程迁移到另一个线程呢?这主要取决于你如何生成它:

  • spawn_local从不涉及移动任务及其结果。
  • spawn_blocking始终涉及最初将任务移动到另一个线程,并将其结果返回,但是任务在执行期间不会移动。
  • spawn 如果使用具有超过 1 个工作线程的多线程运行时,则可能涉及在其生命周期内的任何时刻移动任务,并将其结果移回原处。

就是这样。