我试图了解 tokio
运行时的工作原理,我使用 #[tokio::main]
宏创建了两个运行时(故意),第一个应该执行 function a()
,第二个执行 function b()
。
我假设它们应该永远同时打印“im awake A”
和“im awake B”
(因为它们正在调用一个具有循环的函数async_task
),但事实并非如此,它只打印“im awake A”。
因为每个运行时都有自己的线程池;为什么它们不并行运行?
use std::thread;
fn main() {
a();
b();
}
#[tokio::main]
async fn a() {
tokio::spawn(async move { async_task("A".to_string()).await });
}
pub async fn async_task(msg: String) {
loop {
thread::sleep(std::time::Duration::from_millis(1000));
println!("im awake {}", msg);
}
}
#[tokio::main]
async fn b() {
tokio::spawn(async move { async_task("B".to_string()).await });
}
最佳答案
从同步 main
函数调用 a();
将阻塞,直到 a()
完成。查看此处的文档:https://docs.rs/tokio/1.2.0/tokio/attr.main.html
#[tokio::main] async fn main() { println!("Hello world"); }
Equivalent code not using #[tokio::main]
fn main() { tokio::runtime::Builder::new_multi_thread() .enable_all() .build() .unwrap() .block_on(async { println!("Hello world"); }) }
为了让您的示例正常工作,main()
还可以生成 2 个线程来运行 a、b 并等待它们完成:
fn main() {
let t1 = thread::spawn(|| {
a();
});
let t2 = thread::spawn(|| {
b();
});
t1.join().unwrap();
t2.join().unwrap();
}
编辑:
请注意,a()
和b()
也不需要使用tokio::spawn
,因为它们已经在执行他们自己的异步运行时。
#[tokio::main]
async fn a() -> Result<(), JoinError> {
async_task("A".to_string()).await
}
#[tokio::main]
async fn b() {
async_task("B".to_string()).await
}
如果您在 a
和 b
中使用 tokio::spawn
,则需要等待生成的 future,但是 tokio::spawn(task.await).await
与执行 task.await
基本相同。
关于rust - 无法使用 #[tokio::main] 宏运行两个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74304365/