如何停止从tokio :: io :: lines流阅读?

时间:2019-06-12 05:57:36

标签: rust rust-tokio

我想终止从tokio::io::lines流中读取。我将其与oneshot的未来合并并终止了它,但是tokio::run仍在工作。

use futures::{sync::oneshot, *}; // 0.1.27
use std::{io::BufReader, time::Duration};
use tokio::prelude::*; // 0.1.21

fn main() {
    let (tx, rx) = oneshot::channel::<()>();
    let lines = tokio::io::lines(BufReader::new(tokio::io::stdin()));
    let lines = lines.for_each(|item| {
        println!("> {:?}", item);
        Ok(())
    });

    std::thread::spawn(move || {
        std::thread::sleep(Duration::from_millis(5000));
        println!("system shutting down");
        let _ = tx.send(());
    });

    let lines = lines.select2(rx);

    tokio::run(lines.map(|_| ()).map_err(|_| ()));
}

如何停止阅读?

2 个答案:

答案 0 :(得分:1)

您的策略没有错,但仅适用于不通过Tokio的blocking(传统的冻结should never be done inside a future)执行冻结操作的期货。

您可以通过将tokio::io::lines(..) Future替换为一个简单的间隔Future来进行测试:

let lines = Interval::new(Instant::now(), Duration::from_secs(1));

问题是tokio::io::Stdin内部使用tokio_threadpool::blocking

使用Tokio thread pool blocking(重点是我)时:

  

NB:每当调用   提供的封闭块,即使您使用了将来的组合器   与select 一样-此任务中的其他未来不会取得进展   直到关闭返回。如果不希望这样做,请确保   blocking runs in its自己的任务(例如,使用   futures::sync::oneshot::spawn

由于这将阻塞组合器中的所有其他将来,因此您的Receiver将无法从Sender获得信号,直到阻塞结束。

请参阅How can I read non-blocking from stdin?或您可以使用tokio-stdin-stdout,这将创建一个使用stdin线程中的数据的通道。它还有一个逐行示例。

答案 1 :(得分:0)

感谢您的评论并更正我的句子。

我试图停止这种无阻塞的Future并成功。

let lines = Interval::new(Instant::now(), Duration::from_secs(1));

我的轻描淡写是,在这种情况下,可以用Future包装阻塞的tokio threadpool::blocking。 我待会儿再试。

非常感谢您。