maq*_*ong 6 multithreading multiprocessing rust
我正在尝试使用 Rust 进程的输出。如果进程在一定时间后没有终止,我想终止/终止它。理想情况下,我想将所有内容包装在生成器中,以便我可以逐行迭代输出,但我在 Rust 方面还没有足够的经验。
这是我的代码 ( src/main.rs),使用 subprocess crate:
use subprocess::{Popen, PopenConfig, Redirection};
use std::io::Read;
use std::time::Duration;
fn main() {
let mut p = Popen::create(&["bash", "-c", "echo \"Hi There!\"; sleep 1000"], PopenConfig {stdout: Redirection::Pipe, ..Default::default()}, ).unwrap();
let mut output = p.stdout.take().unwrap();
let thread = std::thread::spawn(move || {
let three_secs = Duration::from_secs(3);
let one_sec = Duration::from_secs(1);
let r = p.wait_timeout(three_secs).unwrap();
match r {
None => {
println!("Wait timed out, terminating process");
p.terminate().unwrap();
let r = p.wait_timeout(one_sec).unwrap();
match r {
None => {
println!("Termination didn't seem to work, killing");
p.kill().unwrap();
},
Some(_) => {
println!("Terminated process successfully");
},
}
p.wait().unwrap();},
Some(_) => { println!("Process returned");},
}
println!("Everything fine");
});
println!("Starting to read output");
let mut output_str = String::new();
output.read_to_string(&mut output_str).unwrap();
println!("Done reading output");
thread.join().unwrap();
println!("Output: {}", output_str);
println!("Hello, world!");
}
Run Code Online (Sandbox Code Playgroud)
我期望以下输出:
Starting to read output
Wait timed out, terminating process
Terminated process successfully
Everything fine
Done reading output
Output: Hi There!
Hello, world!
Run Code Online (Sandbox Code Playgroud)
三秒后该过程结束。但我得到的是
Starting to read output
Wait timed out, terminating process
Terminated process successfully
Everything fine
Run Code Online (Sandbox Code Playgroud)
并且该过程不会终止。
为了完整起见,以下是我Cargo.toml对上面内容的补充src/main.rs:
[package]
name = "subproc"
version = "0.1.0"
authors = ["<snip>"]
edition = "2018"
[dependencies]
subprocess = "0.2.4"
Run Code Online (Sandbox Code Playgroud)
我想找一个箱子来帮助你做到这一点。
也许是这样的: https://docs.rs/wait-timeout/0.2.0/wait_timeout/
以下是适用于捕获 stdout 并逐行迭代它的示例代码:
use std::io::Read;
use std::process::{Command, Stdio};
use std::time::Duration;
use wait_timeout::ChildExt;
fn main() {
let mut child = Command::new("sh")
.arg("-c")
.arg("while true; do date; sleep 1; done")
.stdout(Stdio::piped())
.spawn()
.unwrap();
let secs = Duration::from_secs(5);
let _status_code = match child.wait_timeout(secs).unwrap() {
Some(status) => status.code(),
None => {
child.kill().unwrap();
child.wait().unwrap().code()
}
};
let mut s = String::new();
child.stdout.unwrap().read_to_string(&mut s).unwrap();
for (num, line) in s.split("\n").enumerate() {
println!("{}: {}", num, line);
}
}
Run Code Online (Sandbox Code Playgroud)
印刷:
0: Mon Jun 1 14:42:06 BST 2020
1: Mon Jun 1 14:42:07 BST 2020
2: Mon Jun 1 14:42:08 BST 2020
3: Mon Jun 1 14:42:09 BST 2020
4: Mon Jun 1 14:42:10 BST 2020
5:
Run Code Online (Sandbox Code Playgroud)
如果您想在子进程运行时执行其他工作,则必须使用事件循环或线程。
| 归档时间: |
|
| 查看次数: |
3420 次 |
| 最近记录: |