Dart ProcessSignal
最后修改于 2025 年 4 月 4 日
Dart 中的 ProcessSignal 类提供了一种处理操作系统进程信号的方法。它允许优雅地关闭和自定义信号处理。
进程信号是操作系统发送给程序的通知。常见的信号包括 SIGINT (Ctrl+C) 和 SIGTERM (终止请求)。
基本定义
ProcessSignal 代表可以发送给进程的操作系统信号。它是 Dart 的 dart:io 库的一部分,用于服务器端应用程序。
主要功能包括信号监视、优雅关闭处理和特定于平台的信号支持。并非所有信号在所有平台上都可用。
处理 SIGINT (Ctrl+C)
此示例显示了 Dart 中基本的 SIGINT (Ctrl+C) 信号处理。
import 'dart:io';
void main() async {
ProcessSignal.sigint.watch().listen((signal) {
print('\nReceived SIGINT (signal $signal)');
print('Performing cleanup...');
exit(0);
});
print('Press Ctrl+C to send SIGINT');
await Future.delayed(Duration(minutes: 1));
}
我们为 SIGINT 信号设置了一个监听器。当按下 Ctrl+C 时,我们的处理程序将在退出前执行清理代码。程序等待用户输入。
$ dart main.dart Press Ctrl+C to send SIGINT ^C Received SIGINT (signal ProcessSignal_SIGINT) Performing cleanup...
处理多个信号
此示例演示了如何使用一个监听器处理多个信号。
import 'dart:io';
void main() async {
final signals = [ProcessSignal.sigterm, ProcessSignal.sighup];
for (var signal in signals) {
signal.watch().listen((_) {
print('Received ${signal.toString()}');
exit(0);
});
}
print('Running (PID: ${pid})');
print('Send SIGTERM or SIGHUP to terminate');
await Future.delayed(Duration(minutes: 1));
}
我们为 SIGTERM 和 SIGHUP 信号都创建了监听器。任何一个信号都会触发相同的关闭过程。程序显示其进程 ID。
$ dart main.dart Running (PID: 12345) Send SIGTERM or SIGHUP to terminate Received ProcessSignal_SIGTERM
优雅关闭
此示例实现了带有清理操作的优雅关闭。
import 'dart:io';
class Server {
Future<void> cleanup() async {
print('Closing database connections...');
await Future.delayed(Duration(seconds: 1));
print('Saving state...');
await Future.delayed(Duration(seconds: 1));
print('Cleanup complete');
}
}
void main() async {
final server = Server();
ProcessSignal.sigterm.watch().listen((_) async {
print('\nShutdown initiated');
await server.cleanup();
exit(0);
});
print('Server running (PID: ${pid})');
print('Send SIGTERM to terminate gracefully');
await Future.delayed(Duration(minutes: 1));
}
我们创建了一个带有清理操作的服务器类。当收到 SIGTERM 时,它会在退出前执行异步清理。这确保了数据完整性。
$ dart main.dart Server running (PID: 12345) Send SIGTERM to terminate gracefully Shutdown initiated Closing database connections... Saving state... Cleanup complete
忽略信号
此示例展示了如何在应用程序中忽略特定信号。
import 'dart:io';
void main() async {
// Ignore SIGINT (Ctrl+C)
ProcessSignal.sigint.watch().listen((_) {
print('\nSIGINT ignored (use SIGTERM to terminate)');
});
ProcessSignal.sigterm.watch().listen((_) {
print('\nReceived SIGTERM - shutting down');
exit(0);
});
print('Running (PID: ${pid})');
print('Try Ctrl+C - it will be ignored');
await Future.delayed(Duration(minutes: 1));
}
我们忽略 SIGINT (Ctrl+C),但仍然处理 SIGTERM。这创建了一个更受控制的关闭过程,需要特定的终止信号。
$ dart main.dart Running (PID: 12345) Try Ctrl+C - it will be ignored ^C SIGINT ignored (use SIGTERM to terminate) Received SIGTERM - shutting down
特定于平台的信号
此示例演示了 Dart 中特定于平台的信号处理。
import 'dart:io';
void main() async {
// Platform-specific signals
final signals = [
if (Platform.isLinux || Platform.isMacOS) ProcessSignal.sigusr1,
if (Platform.isWindows) ProcessSignal.sigbreak,
];
for (var signal in signals) {
signal.watch().listen((_) {
print('Received ${signal.toString()}');
// Custom handling for each signal
});
}
print('Running on ${Platform.operatingSystem}');
print('Send platform-specific signals');
await Future.delayed(Duration(minutes: 1));
}
我们根据平台处理不同的信号。Linux/macOS 使用 SIGUSR1,而 Windows 使用 SIGBREAK。代码会适应当前平台。
$ dart main.dart Running on linux Send platform-specific signals Received ProcessSignal_SIGUSR1
最佳实践
- 干净关闭:始终在信号处理程序中执行清理
- 异步处理:对清理操作使用 async/await
- 平台感知:检查每个平台的信号可用性
- 信号文档:记录应用程序中预期的信号
来源
本教程通过实际示例介绍了 Dart 的 ProcessSignal 类,展示了信号处理、优雅关闭和特定于平台的注意事项。
作者
列出 所有 Dart 教程。