我们要完成以下的功能:
捕捉程序中的异常退出信号,并退出前进行一个我们自定义的操作。
在rust中使用linux的信号机制,我们需要引入一个nix库。nix库的crate地址为:https://crates.io/crates/nix.
一、导入nix库
在Cargo.toml中导入:
[dependencies]
nix = "0.23.0"
在rs文件开头写入:
use nix::sys::signal;
二、设置监听信号
let sig_action = signal::SigAction::new(
signal::SigHandler::Handler(signal_handler),
signal::SaFlags::SA_NODEFER,
signal::SigSet::empty(),
);
unsafe {
match signal::sigaction(signal::SIGABRT, &sig_action) {
Ok(_) => {
log::info!("SIGABRT signal has been set.");
},
Err(e) => {
log::error!("SIGABRT signal set failed, {:?}", e);
}
}
match signal::sigaction(signal::SIGINT, &sig_action) {
Ok(_) => {
log::info!("SIGINT signal has been set.");
},
Err(e) => {
log::error!("SIGINT signal set failed, {:?}", e);
}
}
}
1.在创建sig_action的函数内,我们的第一个参数signal::SigHandler::Handler(signal_handler),这其中的signal_handler就是我们自定义的、信号触发后执行的函数:
pub extern "C" fn signal_handler(_: i32) {
match file::write_cursor_into_history_text("cursor/history.text", file::show_position()) {
Ok(()) => {
log::debug!("[signal_handler has been runned.]");
log::info!("the position value written last time is {}.", file::show_position());
},
Err(e) => log::error!("error occurs when write cursor into history text, {:?}", e)
}
std::process::exit(1);
}
这里可以根据个人需要去自定义,我这里完成的功能是在信号发生后,将一个数值写入文件。
2.signal::sigaction函数中的第一个参数,我们这里写了signal::SIGABRT和signal::SIGINT,前者捕获的是函数中的abort异常退出信号,后者捕获的是命令行CTRL+C中断信号。此外还有其他很多信号可以选择,打开任何一本LINUX书籍有关信号的部分都可以查的很清楚。

我们这里选用的SIGABRT信号,在主程序里是这样被调用的:

我们在执行某一重要程序出错时,返回至主函数中,我们对这个错误地处理就是采用std::process::abort()进行异常退出,这样退出时,信号机制就会触发,执行我们自定义的signal_handler函数。
网友评论