如果我的应用程序崩溃,我如何确保派生的子进程被终止?
How do I ensure that a spawned Child process is killed if my app panics?
我正在编写一个启动守护进程并对其进行测试的小测试,例如:
let server = Command::new("target/debug/server").spawn();
// do some tests
server.kill();
测试失败的典型方式是恐慌。不幸的是,这意味着 kill() 永远不会被调用并且测试套件的重复运行失败,因为端口被仍然是 运行.
的旧进程占用
是否有类似 TRAP 功能的东西可以用来确保 Child 被杀死?
您可以将可能引起恐慌的代码放入一个闭包中,然后将该闭包交给 catch_panic
。 catch_panic
的行为与 scoped
或 spawn
ed 线程对 join
ing 的行为相同。它 returns 带有 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);
}
您可以使用标准 RAII 模式来确保 child 线程在您离开给定范围时被终止。如果你只想在恐慌时杀死你的child,你可以插入一个检查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");
}
我正在编写一个启动守护进程并对其进行测试的小测试,例如:
let server = Command::new("target/debug/server").spawn();
// do some tests
server.kill();
测试失败的典型方式是恐慌。不幸的是,这意味着 kill() 永远不会被调用并且测试套件的重复运行失败,因为端口被仍然是 运行.
的旧进程占用是否有类似 TRAP 功能的东西可以用来确保 Child 被杀死?
您可以将可能引起恐慌的代码放入一个闭包中,然后将该闭包交给 catch_panic
。 catch_panic
的行为与 scoped
或 spawn
ed 线程对 join
ing 的行为相同。它 returns 带有 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);
}
您可以使用标准 RAII 模式来确保 child 线程在您离开给定范围时被终止。如果你只想在恐慌时杀死你的child,你可以插入一个检查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");
}