【问题标题】:Letting a parent Rust process terminate without waiting for a subprocess让父 Rust 进程终止而不等待子进程
【发布时间】:2021-11-07 18:53:46
【问题描述】:

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

有没有办法让顶层进程不等待嵌套进程完成?

【问题讨论】:

    标签: unix rust subprocess


    【解决方案1】:

    请查看spawnreference

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

    默认情况下,标准输入、标准输出和标准错误是从父级继承的。

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

    让我们这样演示:

    -> Sub1 -> Sub2

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

    解决办法是;只需使用Stdio::null() 将输出发送到/dev/null,因为您的 Root 进程并不关心 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();
        }
    }
    

    【讨论】:

    • 太棒了,我应该意识到 :)
    猜你喜欢
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    相关资源
    最近更新 更多