什么时候应该使用 Tokio 的 `spawn_blocking`?

bos*_*ton 8 rust async-await rust-tokio

task文档中,有一节讨论了在异步中调用阻塞代码,以及如何避免这种情况,以免过多地阻塞异步线程(https://docs.rs/tokio/1.21.2/tokio/task/ index.html#blocking-and-yielding)。

它还讨论了用于tokio::task::spawn_blocking这些任务的方法,但我想知道在什么时候建议将工作发送到不同的线程?我目前正在编写一个程序,可以恢复大量的 ECDSA 签名,每条消息大约需要 100 微秒,同时进行大量的网络 IO。作为一个具体的例子,这足以使用类似的东西吗spawn_blocking

Joe*_*lay 17

Alice Rhyl(Tokio 开发者之一)有一篇关于异步代码阻塞的很好的博客文章。

您的问题的关键部分之一:

为了了解多少时间才算太多,一个好的经验法则是每次 .await 之间的时间不超过 10 到 100 微秒。也就是说,这取决于您正在编写的应用程序的类型。

鉴于您在每条消息上花费 100 微秒,我认为您可能会认为转移到不同的线程是正确的选择。

这篇文章还给出了如何将工作转移到不同线程上的经验法则:

  • 对于同步 IO,请使用spawn_blocking.
  • 对于 CPU 密集型计算,请使用单独的 fork-join 线程池,例如rayon.
  • 对于永久运行的同步工作(例如侦听数据库连接),请生成您自己的专用线程,以避免从 Tokio/Rayon 池中夺走一个线程。