跳到主要内容

Module coop

搜索

Module coop 

Source
展开描述

用于改进协作式调度的工具。

§Cooperative scheduling

对顶层任务的 poll 的一次调用可能会在返回 Poll::Pending 之前 做大量工作。 如果一个任务长时间运行 而不让出回 executor, 它可能会饿死正在该 executor 上 等待执行的其他任务, 或驱动底层资源。 由于 Rust 没有运行时, 强制抢占一个长时间运行的任务 是困难的。 相反, 本模块为 future 提供了一种 选择性加入的机制, 以与 executor 协作 以避免饥饿。

考虑这样一个 future:

async fn drop_all<I: Stream + Unpin>(mut input: I) {
    while let Some(_) = input.next().await {}
}

它可能看起来无害, 但考虑一下在高负载下 如果输入流始终就绪 会发生什么。 如果我们派生 drop_all, 任务将永远不会让出, 并将饿死同一 executor 上的 其他任务和资源。

为了解决这个问题,Tokio 在许多库函数中 具有显式的让出点,这些点强制任务周期性地返回到 executor。

§unconstrained

If necessary, task::unconstrained lets you opt a future out of Tokio’s cooperative scheduling. When a future is wrapped with unconstrained, it will never be forced to yield to Tokio. 例如:

use tokio::{task, sync::mpsc};

let fut = async {
    let (tx, mut rx) = mpsc::unbounded_channel();

    for i in 0..1000 {
        let _ = tx.send(());
        // This will always be ready. If coop was in effect, this code would be forced to yield
        // periodically. However, if left unconstrained, then this code will never yield.
        rx.recv().await;
    }
};

task::coop::unconstrained(fut).await;

结构体§

Coop
cooperative 创建的、用于保证协作式调度的 future 包装器。
RestoreOnPending
poll_proceed 方法返回的值。
Unconstrained
unconstrained 方法对应的 future。

函数§

consume_budget
消耗一个单位的预算;若 task 的协作预算已耗尽,则将执行权交回 Tokio 运行时。
cooperative
创建一个包装 future,使内部 future 与 Tokio 调度器协作。
has_budget_remaining
如果 task 上还有剩余预算,则返回 true
poll_proceed
减少 task 预算;若预算已耗尽,则返回 Poll::Pending。这表示 task 应让出(yield)给调度器。其他wise, returns RestoreOnPending which can be used to commit the budget consumption.
unconstrained
关闭某个 future 的协作式调度。该 future 永远不会被 Tokio 强制让出。使用它会使你的服务面临饥饿(starvation)的风险,除非该 unconstrained future 自己会让出。