< 返回版块

zhongsigang 发表于 2022-05-28 21:04

Tags:spawn,跨await

在一个async代码块或函数中,若一个变量是非Send的,它在跨.await时就有些讲究了。外层用的是await就没有问题,若用tokio::spawn就出错。

我的问题是:

1 await相较tokio::spawn的特殊处理,据说是为了线程安全。但即使用的是await,看起来没有分叉出新的task,但它也可能被不同的线程来窃取执行,也跨了线程的。这种差异化的对待方式的初衷是什么?

2 用tokio::spawn方式时,除了用临时的代码块来drop外,怎样让非Send的变量跨await?

3 抛砖引玉。请高手就相关问题,作一个较全面的介绍。

示例代码,可在Playgroud上执行。

//# tokio={version="1.17.0", features=["full"]}
use std::error::Error;

#[tokio::main]
pub async fn main() -> Result<(), Box<dyn Error>> {
    let t = async {
        let _a = async_fn().await;
        // tokio::pin!(_a); //no effect
        let _b = async_fn().await;
    };

    // method 1: OK
    // let _ = t.await;

    // method 2: Incorrect
    let handle = tokio::spawn(t);
    let _ = handle.await;

    println!("OK");
    Ok(())
}

async fn async_fn() -> Result<(), Box<dyn Error>> {
    Ok(())
}

评论区

写评论
Jzow 2022-05-30 13:40

可以

作者 zhongsigang 2022-05-28 21:34

很好,谢谢!

--
👇
viruscamp: 用 spawn_local

viruscamp 2022-05-28 21:32
1 共 3 条评论, 1 页