阻塞执行器

大多数异步运行时支持并发运行 IO 任务。这意味着 CPU 的阻塞性任务会阻塞执行器,并阻止执行其他任务。最简单的方法是,尽可能使用异步等效方法。

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Speaker Notes

  • 运行该代码,您会发现休眠操作是连续发生的,而不是并发进行的。

  • "current_thread" 变种将所有任务放在单个线程上。这样做效果会更明显,但 bug 仍然存在于多线程变种中。

  • std::thread::sleep 切换为 tokio::time::sleep,并等待结果。

  • 另一个修复方案是 tokio::task::spawn_blocking,其会生成实际线程并将句柄转换为 Future,且不会阻塞执行器。

  • 不应将任务视为操作系统线程。它们之间并非一对一的映射关系,并且大多数执行器都支持在单个操作系统线程上运行多个任务。尤其是通过 FFI 与其他库交互时,会更容易出现问题,因为在 FFI 中,因为该库可能依赖于线程本地存储或映射到特定的操作系统线程(例如,CUDA)。在这些情况下,首选 tokio::task::spawn_blocking

  • 请谨慎使用同步互斥操作。对 .await 一直执行互斥操作能会导致另一个任务阻塞,并且该任务可能与其在同一线程上运行。