Rust:异步不是并发的



这是Rust书中的例子。

async fn learn_and_sing() {
// Wait until the song has been learned before singing it.
// We use `.await` here rather than `block_on` to prevent blocking the
// thread, which makes it possible to `dance` at the same time.
let song = learn_song().await;
sing_song(song).await;
}
async fn async_main() {
let f1 = learn_and_sing();
let f2 = dance();
// `join!` is like `.await` but can wait for multiple futures concurrently.
// If we're temporarily blocked in the `learn_and_sing` future, the `dance`
// future will take over the current thread. If `dance` becomes blocked,
// `learn_and_sing` can take back over. If both futures are blocked, then
// `async_main` is blocked and will yield to the executor.
futures::join!(f1, f2);
}
fn main() {
block_on(async_main());
}

上面写着

在这个例子中,学习歌曲必须在唱歌之前进行,但是学习和唱歌可以与跳舞同时进行。

但是我不明白这一点。我用Rust写了一小段代码

async fn learn_song() -> &'static str {
println!("learn_song");
"some song"
}
#[allow(unused_variables)]
async fn sing_song(song: &str) {
println!("sing_song");
}
async fn dance() {
println!("dance");
}
async fn learn_and_sing() {
let song = learn_song().await;
std::thread::sleep(std::time::Duration::from_secs(1));
sing_song(song).await;
}
async fn async_main() {
let f1 = learn_and_sing();
let f2 = dance();
let f3 = learn_and_sing();
futures::join!(f1, f2, f3);
}
fn main() {
futures::executor::block_on(async_main());
}

似乎async_main中所有的异步函数都是同步执行的。

输出为

learn_song
sing_song
dance
learn_song
sing_song

如果它们异步运行,我希望在我的输出

中得到类似这样的内容
learn_song
dance
learn_song
sing_song
sing_song

如果我添加一个额外的learn_and_sing调用,它将会像在同步函数中一样打印。

为什么如此?是否有可能使一个真正的异步只使用async/.await和没有线程?

就像tkausl的注释所述,std::thread::sleep使整个线程处于睡眠状态,这将防止线程上的任何代码在睡眠期间执行。您可以使用async_std::任务::睡在这种情况下,因为它是一个异步版本的睡眠功能。

async fn learn_song() -> &'static str {
println!("learn_song");
"some song"
}
#[allow(unused_variables)]
async fn sing_song(song: &str) {
println!("sing_song");
}
async fn dance() {
println!("dance");
}
async fn learn_and_sing() {
let song = learn_song().await;
async_std::task::sleep(std::time::Duration::from_secs(1)).await;
sing_song(song).await;
}
#[async_std::main] 
async fn main() {
let f1 = learn_and_sing();
let f2 = dance();
let f3 = learn_and_sing();
futures::join!(f1, f2, f3);
}

最新更新