我有一个Rust进程,它应该启动一个子进程,然后立即退出。这似乎起作用:
fn main() {
// Intentionally drop the returned Child and exit
Command::new("bash").args(&["-c", "sleep 10s; touch done"]).spawn().unwrap();
}
运行此进程立即退出,bash
进程继续:
$ cargo build; target/debug/demo
$ ps aux | grep bash
dimo414 35959 0.0 0.0 4278616 1484 s001 S 1:12PM 0:00.00 bash -c sleep 10s; touch done
...
- 然而 * 如果我再添加一层并尝试调用我的二进制文件并等待它的完成,它似乎也在等待子进程,这与我在shell中观察到的不同。这是一个MCVE:
fn main() {
let exec = std::env::current_exe().expect("Could not resolve executable location");
// First re-invoke the same binary and await it
if std::env::args().len() < 2 {
println!("Ran Subprocess:\n{:?}", Command::new(exec).arg("").output().unwrap());
} else {
// In that subprocess spawn a long-running process but don't wait
println!("Spawning Subprocess");
Command::new("bash").args(&["-c", "sleep 10s; touch done"]).spawn().unwrap();
}
}
$ cargo build; target/debug/demo
# doesn't terminate until the bash process does
有没有一种方法可以让顶级流程在不等待嵌套流程的情况下完成?
2条答案
按热度按时间esyap4oy1#
请检查
spawn
的引用将命令作为子进程执行,并返回该命令的句柄。
默认情况下,stdin、stdout和stderr从父级继承。
当你把self作为一个子进程运行时,它会产生另一个子进程,继承父进程的stdio。因为你的顶级进程使用
output()
,它会等待子进程完成并收集它所有的输出(参考)。让我们这样演示一下:
根-〉子1-〉子2
Sub 2使用Sub1的stdout通道,Root等待从Sub1收集Sub 2仍在使用的所有输出,在一天结束时Root等待Sub 2完成。
解决方案是;只需使用
Stdio::null()
将输出发送到/dev/null
,因为您的根进程不关心Sub 2的输出。kmpatx3s2#
公认的答案对我不起作用。你应该忽略SIGHUP信号: