跳到主要内容

block_in_place

搜索

函数 block_in_place 

Source
pub fn block_in_place<F, R>(f: F) -> R
where F: FnOnce() -> R,
展开描述

在当前线程上运行所提供的阻塞函数,而不会阻塞 executor。

通常, 在 future 中发出阻塞调用 或执行大量计算 而不让出是有问题的, 因为它可能会阻止 executor 继续驱动其他任务。 调用此函数 会通知 executor 当前正在执行的任务即将阻塞该线程, 以便 executor 能够在 发生这种情况之前 将其拥有的任何其他任务 移交给 新的工作线程。 请参阅 CPU-bound tasks and blocking code 部分了解更多。

请注意, 尽管此函数 避免了饿死其他独立派生的任务, 但在调用 block_in_place 期间, 在同一任务中并发运行的 任何其他代码 都将被挂起。 例如在使用 join! 宏时 可能会发生这种情况。 为避免此问题, 请使用 spawn_blocking 而不是 block_in_place

请注意, 此函数不能在 current_thread 运行时中使用, 因为在这种情况下 没有其他工作线程 可以移交任务。 另一方面, 在运行时之外调用该函数是允许的。 在这种情况下, block_in_place 只会正常调用所提供的闭包。

block_in_place 后运行的代码无法被取消。 当你关闭 executor 时, 它将无限期地等待 所有阻塞操作完成。 你可以使用 shutdown_timeout 在某个超时后停止等待它们。 请注意, 这仍然不会取消任务—— 它们只是被允许 在该方法返回后 继续运行。

§示例

use tokio::task;

task::block_in_place(move || {
    // do some compute-heavy work or call synchronous code
});

block_in_place 中运行的代码 可以使用 block_on 重新进入异步上下文。

use tokio::task;
use tokio::runtime::Handle;

task::block_in_place(move || {
    Handle::current().block_on(async move {
        // do something async
    });
});

§Panics

如果从 current_thread 运行时调用此函数, 则会 panic。