Rust优雅关闭应用插件shutdown-handler的使用,实现安全可靠的进程终止和资源清理
Rust优雅关闭应用插件shutdown-handler的使用,实现安全可靠的进程终止和资源清理
shutdown-handler是一个允许应用程序各部分触发关闭的处理器。
安装
在Cargo.toml中添加依赖:
[dependencies]
shutdown-handler = "0.1.0"
使用示例
下面是一个完整的示例,展示如何使用shutdown-handler实现优雅关闭:
use shutdown_handler::ShutdownHandler;
use std::thread;
use std::time::Duration;
fn main() {
// 创建ShutdownHandler实例
let shutdown = ShutdownHandler::new();
// 获取关闭信号接收器
let mut receiver = shutdown.subscribe();
// 模拟工作线程
let worker = thread::spawn(move || {
loop {
// 检查是否收到关闭信号
if receiver.try_recv().is_ok() {
println!("Worker: Received shutdown signal, cleaning up...");
// 执行清理工作
thread::sleep(Duration::from_secs(1)); // 模拟清理
println!("Worker: Cleanup complete, exiting");
break;
}
// 模拟工作
println!("Worker: Doing some work...");
thread::sleep(Duration::from_secs(1));
}
});
// 模拟主线程工作
for i in 0..5 {
println!("Main: Working {}...", i);
thread::sleep(Duration::from_secs(1));
}
// 触发关闭
println!("Main: Triggering shutdown...");
shutdown.shutdown();
// 等待工作线程完成清理
worker.join().unwrap();
println!("Main: Application shutdown complete");
}
完整示例代码
下面是一个更完整的示例,展示如何在多线程环境中使用shutdown-handler:
use shutdown_handler::ShutdownHandler;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
struct Resource {
name: String,
// 其他资源字段...
}
impl Resource {
fn cleanup(&self) {
println!("Resource {}: Cleaning up...", self.name);
thread::sleep(Duration::from_millis(500)); // 模拟清理耗时
println!("Resource {}: Cleanup completed", self.name);
}
}
fn main() {
// 创建共享的ShutdownHandler
let shutdown = Arc::new(ShutdownHandler::new());
// 创建两个资源
let resource1 = Arc::new(Resource { name: "DB Connection".to_string() });
let resource2 = Arc::new(Resource { name: "File Handler".to_string() });
// 创建工作线程1 - 处理资源1
let shutdown_clone1 = shutdown.clone();
let resource1_clone = resource1.clone();
let worker1 = thread::spawn(move || {
let mut receiver = shutdown_clone1.subscribe();
loop {
if receiver.try_recv().is_ok() {
resource1_clone.cleanup();
break;
}
println!("Worker1: Processing {}...", resource1_clone.name);
thread::sleep(Duration::from_secs(1));
}
});
// 创建工作线程2 - 处理资源2
let shutdown_clone2 = shutdown.clone();
let resource2_clone = resource2.clone();
let worker2 = thread::spawn(move || {
let mut receiver = shutdown_clone2.subscribe();
loop {
if receiver.try_recv().is_ok() {
resource2_clone.cleanup();
break;
}
println!("Worker2: Processing {}...", resource2_clone.name);
thread::sleep(Duration::from_secs(1));
}
});
// 主线程工作
for i in 1..=3 {
println!("Main: Executing task {}...", i);
thread::sleep(Duration::from_secs(2));
}
// 触发优雅关闭
println!("Main: Initiating graceful shutdown...");
shutdown.shutdown();
// 等待所有工作线程完成清理
worker1.join().unwrap();
worker2.join().unwrap();
println!("Main: All resources cleaned up, application exiting");
}
工作原理
- 创建
ShutdownHandler
实例 - 通过
subscribe()
方法获取关闭信号接收器 - 工作线程定期检查是否收到关闭信号
- 主线程调用
shutdown()
方法触发关闭 - 工作线程收到信号后执行清理工作并退出
特点
- 线程安全:可以在多线程环境中使用
- 非阻塞:
try_recv()
方法不会阻塞线程 - 轻量级:实现简洁高效
- 可扩展:支持多个接收器同时监听关闭信号
许可证
可选择以下任一许可证:
- Apache License, Version 2.0
- MIT license
1 回复