如果我的应用程序出现恐慌,我如何确保生成的子进程被终止?

j16*_*16r 8 zombie-process child-process rust

我正在编写一个启动守护进程并对其进行测试的小测试,例如:

let server = Command::new("target/debug/server").spawn();

// do some tests

server.kill();
Run Code Online (Sandbox Code Playgroud)

测试失败的典型方式是恐慌。不幸的是,这意味着 kill() 永远不会被调用并且测试套件的重复运行失败,因为端口被仍在运行的旧进程占用。

是否有类似 TRAP 功能的东西可以用来确保孩子被杀死?

Vae*_*den 6

如果离开给定的范围,您可以使用标准 RAII 模式来确保子线程被终止。如果您只想在您恐慌时杀死您的孩子,您可以在std::thread::panicking 中插入一个检查。

use std::process::{Command,Child};

struct ChildGuard(Child);

impl Drop for ChildGuard {
    fn drop(&mut self) {
        // You can check std::thread::panicking() here
        match self.0.kill() {
            Err(e) => println!("Could not kill child process: {}", e),
            Ok(_) => println!("Successfully killed child process"),
        }
    }
}

fn main() {
    let child = Command::new("/bin/cat").spawn().unwrap();
    let _guard = ChildGuard(child);

    panic!("Main thread panicking");
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为是这样,除非恐慌是在析构函数 [(playpen)](http://is.gd/Zswi2w) 中_开始_的,无论如何,出于各种原因,这在 Rust 中是个坏主意。[std::rt::unwind](http://doc.rust-lang.org/std/rt/unwind/) 中有一些关于展开过程如何发生的文档。 (2认同)

oli*_*obk 4

您可以将可能出现恐慌的代码放入闭包中,并将该闭包赋予catch_panic. 其行为与 a或ed 线程在 ing 上的catch_panic行为相同。如果闭包发生恐慌,它会返回一个带有或 的结果。scopedspawnjoinOk(ClosureRetVal)Err(Box<Any>)

let res = std::thread::catch_panic(|| {
    panic!("blub: {}", 35);
});
if let Err(err) = res {
    let msg: String = *err.downcast().unwrap();
    println!("{}", msg);
}
Run Code Online (Sandbox Code Playgroud)

游戏笔