跳到主要内容

join

搜索

join 

Source
macro_rules! join {
    ($(biased;)? $($future:expr),*) => { ... };
}
展开描述

等待多个并发分支,当 所有 分支都完成时返回。

join! 宏必须在 async 函数、闭包和代码块内部使用。

join! 宏接受一组异步表达式,并在同一个任务上并发地对它们求值。 每个异步表达式都会求值成一个 future,这些 future 在当前任务上进行多路复用。

在处理返回 Result 的异步表达式时,join! 会等待 所有 分支完成,无论其中是否有分支以 Err 完成。 若要在遇到 Err 时提前返回, 请使用 try_join!

§Notes

所提供的 future 是内联存储的,无需分配 Vec

§运行时特征

通过在当前任务上运行所有 async 表达式,这些表达式 能够并发运行,但不能并行运行。这意味着所有 表达式都在同一线程上运行,如果某个分支阻塞了该线程, 所有其他表达式将无法继续。如果需要并行执行, 可以使用 tokio::spawn 生成每个 async 表达式,并将 join handle 传给 join!

§公平性

默认情况下,join! 生成的 future 在每次被唤醒时, 都会轮换决定首先轮询哪个所包含的 future。

可以通过在宏的开头添加 biased; 来覆盖此行为。 详细信息请参见示例。这将使 join 按照 future 从上到下出现的顺序进行轮询。

如果你的 future 仍会交互,且知道探造的顺序是否重要,则可能需要这个宏。

但在这种模式下有一个重要的注意事项。确保 future 的 poll 顺序是公平的就成了你的 责任。例如,如果你要 join 一个流和一个关闭 future,且该流 每次 poll 时都有大量消息需要长时间处理,那么你应该 把关闭 future 放在 join! 列表的更前面,以确保它 始终被 poll,而不会因流 future 长时间返回 Poll::Pending 而被延迟。

§示例

两个分支的基本 join

async fn do_stuff_async() {
    // async work
}

async fn more_async_work() {
    // more here
}

let (first, second) = tokio::join!(
    do_stuff_async(),
    more_async_work());

// do something with the values

使用 biased; 模式来控制 poll 顺序。

async fn do_stuff_async() {
    // async work
}

async fn more_async_work() {
    // more here
}

let (first, second) = tokio::join!(
    biased;
    do_stuff_async(),
    more_async_work()
);

// do something with the values