rust - 如何在 Tokio 中为 CPU 密集型工作创建专用线程池?
问题描述
我有一个基于Tokio运行时的 Rust 异步服务器。它必须同时处理对延迟敏感的 I/O 绑定请求和繁重的 CPU 绑定请求。
我不想让 CPU 密集型任务独占 Tokio 运行时并饿死 I/O 密集型任务,所以我想将 CPU 密集型任务卸载到一个专用的、隔离的线程池(隔离是这里的关键,所以spawn_blocking
/block_in_place
在一个共享线程池上是不够的)。如何在 Tokio 中创建这样的线程池?
启动两个运行时的幼稚方法会遇到错误:
线程“tokio-runtime-worker”在“无法从运行时内启动运行时”时惊慌失措。发生这种情况是因为一个函数(如
block_on
)在线程被用于驱动异步任务时试图阻塞当前线程。
use tokio; // 0.2.20
fn main() {
let mut main_runtime = tokio::runtime::Runtime::new().unwrap();
let cpu_pool = tokio::runtime::Builder::new().threaded_scheduler().build().unwrap();
let cpu_pool = cpu_pool.handle().clone(); // this is the fix/workaround!
main_runtime.block_on(main_runtime.spawn(async move {
cpu_pool.spawn(async {}).await
}))
.unwrap().unwrap();
}
Tokio 可以允许两个单独的运行时吗?有没有更好的方法在 Tokio 中创建一个隔离的 CPU 池?
解决方案
虽然 Tokio 已经有一个线程池,但Tokio 的文档建议:
如果您的代码受 CPU 限制并且您希望限制用于运行它的线程数,您应该在另一个线程池(例如rayon )上运行它。当人造丝任务完成时,您可以使用oneshot通道将结果发送回 Tokio 。
所以,如果你想创建一个线程池来大量使用 CPU,一个好方法是使用像 Rayon 这样的 crate 并将结果发送回 Tokio 任务。
推荐阅读
- arcgis-runtime - ArcGIS Runtime:如何将点的单位从度转换为米
- html - 将鼠标悬停在 li 上时,如何使 aa 标签下划线
- php - SQLite,PHP - 准备方法无法准备 upsert 查询
- angularjs - 如何在 AngularJS 中缓存 Ajax 'POST' 请求的响应
- python-3.x - TimeTrigger Azure 函数在 Azure 门户中没有出现模块错误,但在 VSC 中运行良好
- html - 无法为多个问题选择单选按钮选项
- javascript - 显示选项卡菜单的问题
- php - 数据显示 Json 中每个元素的最后一个元素数据
- c - 文件传输完成,但程序未收到文件结束条件以停止用 C 编写
- sql - 一列中两种不同条件的总和