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