rust - 如何运行多个并行调用 thread::sleep 的 future ?

标签 rust future

<分区>

我有一个缓慢的 future ,在运行完成之前阻塞 1 秒。

我已尝试使用 join 组合器,但复合 future my_app 按顺序执行 future :

#![feature(pin, futures_api, arbitrary_self_types)]

extern crate futures; // v0.3

use futures::prelude::*;
use futures::task::Context;
use std::pin::PinMut;
use std::{thread, time};
use futures::executor::ThreadPoolBuilder;

struct SlowComputation {}

impl Future for SlowComputation {
    type Output = ();

    fn poll(self: PinMut<Self>, _cx: &mut Context) -> Poll<Self::Output> {
        let millis = time::Duration::from_millis(1000);
        thread::sleep(millis);

        Poll::Ready(())
    }
}

fn main() {
    let fut1 = SlowComputation {};
    let fut2 = SlowComputation {};
    let my_app = fut1.join(fut2);

    ThreadPoolBuilder::new()
        .pool_size(5)
        .create()
        .expect("Failed to create threadpool")
        .run(my_app);
}

为什么 join 会那样工作?我预计 future 会在不同的线程上产生。

实现目标的正确方法是什么?

cargo .toml:

[dependencies]
futures-preview = "0.3.0-alfa.6"

结果:

$ time target/debug/futures03

real    0m2.004s
user    0m0.000s
sys 0m0.004s

最佳答案

如果您将 futures 与 join() 相结合,它们将被转换为一个单个任务,在一个单个线程上运行。

如果 future 表现良好,它们将以事件驱动(异步)的方式并行运行。您会希望您的应用程序休眠 1 秒钟。

但不幸的是,您实现的 future 表现良好。它阻塞当前线程一秒钟,不允许在此期间完成任何其他工作。因为 future 在同一个线程上运行,所以它们不能同时运行。您的应用程序将休眠 2 秒。

请注意,如果您将示例更改为以下内容, future 将保持独立的任务,您可以在线程池上独立并行运行它们:

fn main() {
    let fut1 = SlowComputation {};
    let fut2 = SlowComputation {};

    let mut pool = ThreadPoolBuilder::new()
        .pool_size(5)
        .create()
        .expect("Failed to create threadpool");

    pool.spawn(fut1);
    pool.run(fut2);
}

强烈不鼓励编写阻塞主线程的 future,在实际应用程序中,您可能应该使用库提供的计时器,例如 tokio::timer::Delaytokio::timer::timeout::Timeout .

关于rust - 如何运行多个并行调用 thread::sleep 的 future ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52313031/

相关文章:

rust - 如何在实现特征时明确指定生命周期?

rust - 为什么这个 MutexGuard 没有被丢弃?

asynchronous - 如何有条件地退还不同类型的 future ?

scala - 在接收方法中调用 Future 并在此之后停止 actor

list - 为什么我对链表的 drop 迭代实现仍然会导致堆栈溢出?

random - 如何在 Rust 中生成一串具有特定大小的随机 ASCII 可打印字符?

返回 Vec<&str> 时字符串的生命周期

scala - 重新开始的我的 Actor 所产生的 future 会发生什么

java - 当代码抛出异常时,如何使用 Java 8 CompletableFuture 干燥异常处理?

java - Callable和Future的实际实现