我正在测试使用tokio::spawn创建的任务在主线程终止时的行为。根据tokio文档,当运行时关闭时,所有任务都会被放弃。
然而,当按照以下方式运行测试时,即使运行时终止,任务似乎也没有被终止。不能保证启动的任务将执行完成。当运行时关闭时,所有未完成的任务都将被放弃,而不管该任务的生命周期如何。
Cargo.toml
[package]
name = "tokio_test"
version = "0.1.0"
edition = "2021"
[dependencies]
tokio = { version = "1", features = ["rt", "test-util", "macros", "rt-multi-thread"]}
main.rs
use std::{thread, time};
#[tokio::main]
async fn main() {
println!("tokio test - main thread...");
tokio::spawn(async move {
let mut i = 0;
loop {
println!(
"tokio test - tokio spawn(worker) thread... sleep(1): {}/10",
i
);
thread::sleep(time::Duration::from_millis(1000));
i += 1;
if i > 3 {
break;
}
}
});
thread::sleep(time::Duration::from_millis(1000));
println!("tokio test - main thread... closed ");
}
输出
tokio test - main thread...
tokio test - tokio spawn(worker) thread... sleep(1): 0/10
tokio test - main thread... closed
tokio test - tokio spawn(worker) thread... sleep(1): 1/10
tokio test - tokio spawn(worker) thread... sleep(1): 2/10
tokio test - tokio spawn(worker) thread... sleep(1): 3/10
问题
问题1:如果我想在运行时终止时自动终止任务,我是否必须通过任务的JoinHandle直接终止它们?
问题2:如果我在tokio::spawn内部调用tokio::spawn,嵌套任务将不起作用。我不能像这样嵌套tokio::spawn吗?(它显示与输出相同的结果)
tokio::spawn(async move {
let mut i = 0;
loop {
println!(
"tokio test - tokio spawn(worker) thread... sleep(1): {}/10",
i
);
thread::sleep(time::Duration::from_millis(1000));
i += 1;
/* nested spawn */
tokio::spawn(async move {
println!("worker thread in worker, sleep(1): 10");
thread::sleep(time::Duration::from_millis(1000));
});
if i > 3 {
break;
}
}
});
tokio::task::sleep
和.await
,以便内部任务有机会运行。现在它只在创建时运行一次,而不是在睡眠期间运行。 - Michael