我想终止从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(|_| ()));
}
如何停止阅读?
答案 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
。
我待会儿再试。
非常感谢您。