众所周知,异步代码不应该在两次等待之间运行很长时间.尽管如此,有时异步代码需要执行长时间运行的操作,如阻塞IO.在这些情况下,通常的建议似乎是使用tokio::task::spawn_blocking(例如,请参阅Tokio开发人员之一的this blog post).

The trouble is, as with regular tokio::task::spawn, spawn_blocking must own all the data it accesses (or it must have 'static lifetime), even when immediately awaiting it (see Why does `tokio::spawn` requires a `'static` lifetime if I immediately await it?).

因此,这样的代码将不会编译:

fn foo(my_ref: &ExpensiveToClone) {
    // Do some stuff that blocks for IO
}

async fn foo_the_reference(my_ref: &ExpensiveToClone) {
    spawn_blocking(move || {
        foo(my_ref);
    }).await;
}

有没有办法在没有这种静态生命周期限制的情况下从异步代码运行阻塞代码?

推荐答案

如果使用Tokio,可以使用tokio::task::block_in_place.它仍然阻塞该线程,但它至少通知执行器它将被阻塞,并且应该将其任务卸载到其他线程.

Rust相关问答推荐

为什么拥有的trait对象的相等运算符移动了正确的操作数?

为什么对不可复制数据的引用的取消引用没有O权限来避免Rust中的双重释放?

如何最好地并行化修改同一Rust向量的多个切片的代码?

无法理解铁 rust &S错误处理

在Rust中宏的表达式中提取对象

我是否可以在Ruust中修改 struct 实例上的字符串,以使其在修改后具有相同的字符串生存期?

如果死 struct 实现了/派生了一些特征,为什么Rust会停止检测它们?

在Rust中,Box:ed struct 与普通 struct 在删除顺序上有区别吗?

使用 select 处理 SIGINT 和子等待!无阻塞

在使用粗粒度锁访问的数据 struct 中使用 RefCell 是否安全?

使用启用优化的 alloc 会导致非法指令崩溃

从 rust 函数返回 &HashMap

为什么某些类型参数仅在特征边界中使用的代码在没有 PhantomData 的情况下进行编译?

从Rust 的临时文件中创建引用是什么意思?

Rust/Serde/HTTP:序列化`Option`

Rust 将特性传递给依赖项

使用部分键从 Hashmap 中检索值

隐式类型闭包的错误生命周期推断

Rust - 在线程之间不安全地共享没有互斥量的可变数据

HashMap entry() 方法使borrow 的时间比预期的长