让父Rust进程终止而不等待子进程



我有一个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

是否有一种方法允许顶层进程完成而不等待嵌套进程?

请查阅spawn的参考

将命令作为子进程执行,并返回句柄给它。

默认情况下,stdin、stdout和stderr从父节点继承。

当你将self作为子进程运行时,它会从父进程中继承stdio而生成另一个子进程。由于您的顶级进程使用output(),它将等待子进程完成并收集其所有输出(参考).

让我们像这样演示:

→Sub1→Sub2

Sub2使用Sub1的标准输出通道,Root等待收集Sub1的所有输出,Sub2仍在使用,在一天结束时,Root等待Sub2完成。

解决方案;简单地使用Stdio::null()发送输出到/dev/null,因为您的根进程不关心Sub2的输出。

fn main() {
let exec = std::env::current_exe().expect("Could not resolve executable location");
if std::env::args().len() < 2 {
println!(
"Ran Subprocess:n{:?}",
Command::new(exec).arg("").output().unwrap()
);
} else {
println!("Spawning Subprocess");
Command::new("bash")
.stdout(Stdio::null())
.stderr(Stdio::null())
.args(&["-c", "sleep 10s; touch done"])
.spawn()
.unwrap();
}
}

接受的答案对我不起作用。你应该忽略SIGHUP信号:

use std::os::unix::process::CommandExt;
fn main() -> std::io::Result<()> {
let mut command = std::process::Command::new("bash");
command.args(["-c", "pwd; sleep 5; touch helloworld"]);
unsafe {
command.pre_exec(|| {
// Ignore SIGHUP signal to prevent child process from being killed when parent exits
libc::signal(libc::SIGHUP, libc::SIG_IGN);
Ok(())
});
}
command.spawn()?;
Ok(())
}

最新更新