生锈:异步不同意

发布于 2025-02-13 01:22:38 字数 2223 浏览 0 评论 0原文

这是Rust Book中的示例

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_and_sing的额外调用,我希望在输出中得到类似的东西

learn_song
dance
learn_song
sing_song
sing_song

,它会像同步函数中一样打印钢。

问题为什么?是否可以仅使用async/.await和无线程制作真实的异步?

Here's the example from the Rust book.

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());
}

And it's says

In this example, learning the song must happen before singing the song, but both learning and singing can happen at the same time as dancing.

But I can't get this point. I wrote a short code in 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());
}

And it seems like all the async functions in the async_main executed synchronously.

The output is

learn_song
sing_song
dance
learn_song
sing_song

If they run asynchronously, I would expect to get something like this in my output

learn_song
dance
learn_song
sing_song
sing_song

If I add an extra call of learn_and_sing it would steel be printed like in a synchronous function.

The question Why so? Is it possible to make a real async using only async/.await and no threads?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

指尖凝香 2025-02-20 01:22:38

就像Tkausl的评论所述,STD :: Thread :: Sleep select sheep sheck the the the the 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);
}

Like tkausl's comment states, std::thread::sleep makes the whole thread sleep, which prevents any code on the thread from executing during the sleeping duration. You could use async_std::task::sleep in this situation, as it is an asynchronous version of the sleep function.

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文