我正在编写一个小测试,启动守护进程并对其进行测试,例如:
let server = Command::new("target/debug/server").spawn();
// do some tests
server.kill();
测试失败的典型方法是恐慌。不幸的是,这意味着kill()永远不会被调用,并且测试套件的重复运行失败,因为端口是由仍在运行的旧进程占用的。
是否有类似TRAP功能的东西我可以用来确保Child被杀?
答案 0 :(得分:4)
您可以将可能恐慌的代码放入闭包中,并将该闭包赋予catch_panic
。 catch_panic
的行为与scoped
或spawn
ed线程对join
的行为方式相同。如果关闭恐慌,它会返回带有Ok(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);
}
答案 1 :(得分:3)
如果离开给定范围,可以使用标准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");
}