在一个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(())
}
1
共 3 条评论, 1 页
评论区
写评论可以
很好,谢谢!
--
👇
viruscamp: 用 spawn_local
用 spawn_local