如何 运行 并行调用 thread::sleep 的多个期货?
How to run multiple futures that call thread::sleep in parallel?
我有一个缓慢的未来,在 运行 完成之前阻塞 1 秒。
我试过使用 join
组合器,但复合未来 my_app
按顺序执行未来:
#![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
会那样工作?我预计期货会在不同的线程上产生。
实现目标的正确方法是什么?
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()
组合,它们将被转换为 单个任务 ,运行 在 单线程上运行.
如果期货表现良好,它们将运行以事件驱动(异步)方式并行。您希望您的应用程序休眠 1 秒。
但不幸的是,您实施的未来 不 表现良好。它阻塞当前线程一秒钟,不允许在此期间完成任何其他工作。因为期货在同一个线程上运行,所以它们不能同时运行。您的应用程序将休眠 2 秒。
请注意,如果您将示例更改为以下内容,未来将保持独立的任务,您可以 运行 它们在您的线程池中独立并行:
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);
}
不鼓励编写阻塞主线程的 futures ,在实际应用程序中,您可能应该使用库提供的计时器,例如 tokio::timer::Delay
or tokio::timer::timeout::Timeout
.
我有一个缓慢的未来,在 运行 完成之前阻塞 1 秒。
我试过使用 join
组合器,但复合未来 my_app
按顺序执行未来:
#![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
会那样工作?我预计期货会在不同的线程上产生。
实现目标的正确方法是什么?
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()
组合,它们将被转换为 单个任务 ,运行 在 单线程上运行.
如果期货表现良好,它们将运行以事件驱动(异步)方式并行。您希望您的应用程序休眠 1 秒。
但不幸的是,您实施的未来 不 表现良好。它阻塞当前线程一秒钟,不允许在此期间完成任何其他工作。因为期货在同一个线程上运行,所以它们不能同时运行。您的应用程序将休眠 2 秒。
请注意,如果您将示例更改为以下内容,未来将保持独立的任务,您可以 运行 它们在您的线程池中独立并行:
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);
}
不鼓励编写阻塞主线程的 futures ,在实际应用程序中,您可能应该使用库提供的计时器,例如 tokio::timer::Delay
or tokio::timer::timeout::Timeout
.