【问题标题】:How to race a collection of Futures in Rust?如何在 Rust 中对 Futures 的集合进行竞赛?
【发布时间】:2020-09-03 02:25:35
【问题描述】:

给定Futures 的集合,比如Vec<impl Future<..>>,我如何才能阻止并同时运行所有Futures,直到第一个Future 准备好?

我能找到的最接近的功能是select macro(也是available in Tokio)。不幸的是,它只适用于明确数量的Futures,而不是处理它们的集合。

在 Javascript 中有一个与此功能等效的功能,称为 Promise.race。有没有办法在 Rust 中做到这一点?

或者也许有一种方法可以使用另一种模式来实现这个用例,也许是通道?

【问题讨论】:

  • 我现在无法写出正确的答案,但请检查FuturesUnordered (docs.rs/futures/0.3.5/futures/stream/…) 是否是您想要的。
  • 我想你可能想要futures::future::select_all
  • 这能回答你的问题吗? How can I spawn asynchronous methods in a loop? 具体看答案中定义的join_parallel 函数。
  • @user4815162342 我认为该建议不能回答问题,因为join_parallel 需要等待所有 个期货完成执行。相反,我只想等到最快的未来完成,然后解除阻塞线程。此外,并行执行期货不是这个问题的要求。但是感谢您的评论!

标签: asynchronous concurrency rust future


【解决方案1】:

我想出了一个使用 select_all function from the futures 库的解决方案。

这里有一个简单的例子来演示如何使用它来竞争期货集合:

use futures::future::select_all;
use futures::FutureExt;
use tokio::time::{delay_for, Duration};

async fn get_async_task(task_id: &str, seconds: u64) -> &'_ str {
    println!("starting {}", task_id);
    let duration = Duration::new(seconds, 0);

    delay_for(duration).await;

    println!("{} complete!", task_id);
    task_id
}

#[tokio::main]
async fn main() {
    let futures = vec![

        // `select_all` expects the Futures iterable to implement UnPin, so we use `boxed` here to
        // allocate on the heap:
        // https://users.rust-lang.org/t/the-trait-unpin-is-not-implemented-for-genfuture-error-when-using-join-all/23612/3
        // https://docs.rs/futures/0.3.5/futures/future/trait.FutureExt.html#method.boxed

        get_async_task("task 1", 5).boxed(),
        get_async_task("task 2", 4).boxed(),
        get_async_task("task 3", 1).boxed(),
        get_async_task("task 4", 2).boxed(),
        get_async_task("task 5", 3).boxed(),
    ];

    let (item_resolved, ready_future_index, _remaining_futures) =
        select_all(futures).await;

    assert_eq!("task 3", item_resolved);
    assert_eq!(2, ready_future_index);
}

这是上面代码的链接: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f32b2ed404624c1b0abe284914f8658d

感谢@Herohtar 在上面的cmets 中推荐select_all

【讨论】:

    猜你喜欢
    • 2022-12-12
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 2021-10-07
    • 2019-10-20
    • 2011-08-21
    • 2018-11-23
    • 1970-01-01
    相关资源
    最近更新 更多