在等待时杀死子进程 [英] Kill child process while waiting for it

查看:31
本文介绍了在等待时杀死子进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想执行另一个进程,通常想等到它完成.假设我们在线程 T1 中生成并等待进程:

I want to execute another process and normally want to wait until it has finished. Lets say we spawn and wait for the process in thread T1:

let child = Command::new("rustc").spawn().unwrap();
child.wait();

现在,如果发生特殊事件(T0 正在等待哪个线程),我想杀死生成的进程:

Now, if a special event occurs (which thread T0 is waiting for) I want to kill the spawned process:

if let Ok(event) = special_event_notifier.recv() {
    child.kill();
}

但我看不出有什么方法可以做到:killwait 都对 Child 进行可变引用,因此是相互的独家的.在调用 wait 之后,没有人可以再引用 child.

But I don't see a way to do it: both kill and wait take a mutable reference to Child and are therefore mutually exclusive. After calling wait no one can have any reference to child anymore.

我找到了 wait-timeout 箱子,但是我想知道是否有其他方法.

I've found the wait-timeout crate, but I want to know if there's another way.

推荐答案

如果子进程在完成之前没有关闭 stdout,可能会等待读取 stdout.这是一个例子

If the child subprocess do not close stdout before finishing, it's possible to wait reading stdout. Here is an example

use std::io::Read;
use std::process::*;
use std::thread;
use std::time::Duration;

fn wait_on_output(mut out: ChildStdout) {
    while out.read_exact(&mut [0; 1024]).is_ok() { }
}

fn wait_or_kill(cmd: &mut Command, max: Duration) {
    let mut child = cmd.stdout(Stdio::piped())
                       .spawn()
                       .expect("Cannot spawn child");

    let out = child.stdout.take().expect("No stdout on child");

    let h = thread::spawn(move || {
        thread::sleep(max);
        child.kill().expect("Cannot kill child");
        println!("{:?}", child.wait());
    });

    wait_on_output(out);
    h.join().expect("join fail");
}

fn main() {
    wait_or_kill(Command::new("sleep").arg("1"), Duration::new(2, 0));
    wait_or_kill(Command::new("sleep").arg("3"), Duration::new(2, 0));
}

这个程序在我的系统上的输出是

The output of this program on my system is

Ok(ExitStatus(ExitStatus(0)))
Ok(ExitStatus(ExitStatus(9)))

虽然不在文档中,但杀死一个完成的孩子会返回 Ok.

Although not in the docs, killing a finished child returns Ok.

这是有效的,因为杀死进程会关闭与其关联的文件.但是,如果子进程产生新进程,杀死子进程可能不会杀死这些其他进程,并且它们可能会保持标准输出打开.

This works because killing a process close the files associated with it. However, if the child spawn new processes, killing the child may not kill these other processes and they may keep the stdout opened.

这篇关于在等待时杀死子进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆