rust - 如何将任务添加到在另一个线程上运行的 Tokio 事件循环?
问题描述
我想在 Rocket 服务器旁边启动一个 Tokio 事件循环,然后稍后将事件添加到这个循环中。我读了有没有办法在新线程上启动 tokio::Delay 以允许主循环继续?,但我仍然不清楚如何实现我的目标。
解决方案
正如文档所述:
返回的句柄可用于生成在此运行时运行的任务,并且可以克隆以允许将其移动
Handle
到其他线程。
这是一个在一个线程中启动事件循环并在其上生成第二个线程任务的示例。
use futures::future; // 0.3.5
use std::{thread, time::Duration};
use tokio::{runtime::Runtime, time}; // 0.2.21
fn main() {
let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel();
let (handle_tx, handle_rx) = std::sync::mpsc::channel();
let tokio_thread = thread::spawn(move || {
let mut runtime = Runtime::new().expect("Unable to create the runtime");
eprintln!("Runtime created");
// Give a handle to the runtime to another thread.
handle_tx
.send(runtime.handle().clone())
.expect("Unable to give runtime handle to another thread");
// Continue running until notified to shutdown
runtime.block_on(async {
shutdown_rx.await.expect("Error on the shutdown channel");
});
eprintln!("Runtime finished");
});
let another_thread = thread::spawn(move || {
let handle = handle_rx
.recv()
.expect("Could not get a handle to the other thread's runtime");
eprintln!("Another thread created");
let task_handles: Vec<_> = (0..10)
.map(|value| {
// Run this future in the other thread's runtime
handle.spawn(async move {
eprintln!("Starting task for value {}", value);
time::delay_for(Duration::from_secs(2)).await;
eprintln!("Finishing task for value {}", value);
})
})
.collect();
// Finish all pending tasks
handle.block_on(async move {
future::join_all(task_handles).await;
});
eprintln!("Another thread finished");
});
another_thread.join().expect("Another thread panicked");
shutdown_tx
.send(())
.expect("Unable to shutdown runtime thread");
tokio_thread.join().expect("Tokio thread panicked");
}
Runtime created
Another thread created
Starting task for value 0
Starting task for value 1
Starting task for value 2
Starting task for value 3
Starting task for value 4
Starting task for value 5
Starting task for value 6
Starting task for value 7
Starting task for value 8
Starting task for value 9
Finishing task for value 0
Finishing task for value 5
Finishing task for value 4
Finishing task for value 3
Finishing task for value 9
Finishing task for value 2
Finishing task for value 1
Finishing task for value 7
Finishing task for value 8
Finishing task for value 6
Another thread finished
Runtime finished
Tokio 0.1的解决方案可在本文的修订历史中找到。
也可以看看:
推荐阅读
- javascript - Javascript:有什么理由不使用 ** 求幂
- javascript - 当代码相同时,为什么在 repli 中使用我的代码而不是 vsc 会给我不同的结果?
- python - Python:列表索引行为异常,返回新生成的字符串而不是项目
- javascript - 如何使用 jQuery 为数量制作“选择选项”选择选项
- visual-studio-code - vscode remote-ssg:服务器状态检查失败 - 等待并重试
- python - 增加已用内存时 Chrome 浏览器崩溃
- java - 无法打开 Web 服务测试器页面
- javascript - 使用 .serializeArray() Javascript 时如何自定义键值对?
- c - 我在文本文件中有两行数据。我必须从文本文件中读取这两行数据并将其存储在两个不同的数组中
- c# - 如何从上一页的文本框中获取变量到下一页?