【问题标题】:Why are spawned futures not executed by tokio_core::reactor::Core?为什么 tokio_core::reactor::Core 不执行生成的期货?
【发布时间】:2018-10-27 07:16:44
【问题描述】:
extern crate tokio; // 0.1.8

use tokio::prelude::*;

fn create_a_future(x: u8) -> Box<Future<Item = (), Error = ()>> {
    Box::new(futures::future::ok(2).and_then(|a| {
        println!("{}", a);
        Ok(())
    }))
}

fn main() {
    let mut eloop = tokio_core::reactor::Core::new().unwrap();
    let handle = eloop.handle();

    for x in 0..10 {
        let f = create_a_future(x);
        handle.spawn(f);
    }
}

我希望这会打印到标准输出,但它没有发生。我是否以错误的方式使用spawn

【问题讨论】:

标签: rust rust-tokio


【解决方案1】:

正如 cmets 中已经提到的,您正在设置一堆计算,但从未运行任何一个。与迭代器一样,您可以将期货视为 惰性。当您直接创建未来但从不使用它时,编译器通常会告诉您这一点。在这里,您正在催生未来,因此您不会收到警告,但没有任何东西可以驱动 Tokio 反应堆。

在许多情况下,你有一个特定的未来想要运行,你会驱动反应堆直到它完成。在其他情况下,您“永远”运行反应器,无休止地处理新工作。

在这种情况下,您可以使用Core::turn

fn main() {
    let mut eloop = tokio_core::reactor::Core::new().unwrap();
    let handle = eloop.handle();

    for x in 0..10 {
        let f = create_a_future(x);
        handle.spawn(f);
    }

    eloop.run(None);
}

eloop.turn(None);

-> Box<Future<Item = (), Error = ()>>

在现代 Rust 中,您不需要(也可能不应该)这样做。最好返回匿名类型:

fn create_a_future() -> impl Future<Item = (), Error = ()> {
    futures::future::ok(2).and_then(|a| {
        println!("{}", a);
        Ok(())
    })
}
 tokio_core::reactor::Core

我的理解是,这个级别的 Tokio 是为更复杂的设置保留的。很多人可以直接使用tokio::runtokio::spawn

fn main() {
    tokio::run(futures::lazy(|| {
        for _ in 0..10 {
            tokio::spawn(create_a_future());
        }
        Ok(())
    }))
}

【讨论】:

    猜你喜欢
    • 2014-09-23
    • 2014-08-08
    • 1970-01-01
    • 2023-01-30
    • 1970-01-01
    • 1970-01-01
    • 2015-11-08
    • 2021-08-28
    • 1970-01-01
    相关资源
    最近更新 更多