有没有办法杀死 Rust 中的(子)任务,即使它正在执行一些长的外部函数调用,比如阻塞读取?
不。
也可以看看:
有没有办法进行非阻塞读取 [...] 以便 Rust 保持对任务的控制?
是的。
也可以看看:
在 POSIX 文件描述符上
是的。
也可以看看:
我如何对信号做出反应
决定你想要的平台支持,然后选择一个合适的 crate。
也可以看看:
把它们放在一起
use future::Either;
use signal_hook::iterator::Signals;
use std::os::unix::io::FromRawFd;
use tokio::{fs::File, io, prelude::*};
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
fn main() -> Result<()> {
let signals = Signals::new(&[signal_hook::SIGUSR1])?;
let signals = signals.into_async()?;
let input = unsafe { std::fs::File::from_raw_fd(5) };
let input = File::from_std(input);
let lines = io::lines(std::io::BufReader::new(input));
let signals = signals.map(Either::A);
let lines = lines.map(Either::B);
let combined = signals.select(lines);
tokio::run({
combined
.map_err(|e| panic!("Early error: {}", e))
.for_each(|v| match v {
Either::A(signal) => {
println!("Got signal: {:?}", signal);
Err(())
}
Either::B(data) => {
println!("Got data: {:?}", data);
Ok(())
}
})
});
Ok(())
}
货运.toml
[package]
name = "future_example"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]
edition = "2018"
[dependencies]
tokio = "0.1.22"
signal-hook = { version = "0.1.9", features = ["tokio-support"] }
垫片
#!/bin/bash
set -eu
exec 5< /tmp/testpipe
exec ./target/debug/future_example
执行
cargo build
mkfifo /tmp/testpipe
./shim.sh
另一个终端
printf 'hello\nthere\nworld' > /tmp/testpipe
kill -s usr1 $PID_OF_THE_PROCESS