Dart ProcessSignal
last modified April 4, 2025
The ProcessSignal
class in Dart provides a way to handle operating
system process signals. It allows graceful shutdown and custom signal handling.
Process signals are notifications sent to a program by the operating system. Common signals include SIGINT (Ctrl+C) and SIGTERM (termination request).
Basic Definition
ProcessSignal
represents operating system signals that can be sent
to a process. It's part of Dart's dart:io
library for server-side
applications.
Key features include signal watching, graceful shutdown handling, and platform- specific signal support. Not all signals are available on all platforms.
Handling SIGINT (Ctrl+C)
This example shows basic SIGINT (Ctrl+C) signal handling in Dart.
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)); }
We set up a listener for SIGINT signals. When Ctrl+C is pressed, our handler executes cleanup code before exiting. The program waits for user input.
$ dart main.dart Press Ctrl+C to send SIGINT ^C Received SIGINT (signal ProcessSignal_SIGINT) Performing cleanup...
Handling Multiple Signals
This example demonstrates handling multiple signals with one listener.
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)); }
We create listeners for both SIGTERM and SIGHUP signals. Either signal will trigger the same shutdown procedure. The program displays its process ID.
$ dart main.dart Running (PID: 12345) Send SIGTERM or SIGHUP to terminate Received ProcessSignal_SIGTERM
Graceful Shutdown
This example implements a graceful shutdown with cleanup operations.
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)); }
We create a server class with cleanup operations. When SIGTERM is received, it performs async cleanup before exiting. This ensures data integrity.
$ dart main.dart Server running (PID: 12345) Send SIGTERM to terminate gracefully Shutdown initiated Closing database connections... Saving state... Cleanup complete
Ignoring Signals
This example shows how to ignore certain signals in your application.
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)); }
We ignore SIGINT (Ctrl+C) while still handling SIGTERM. This creates a more controlled shutdown process requiring specific termination signals.
$ dart main.dart Running (PID: 12345) Try Ctrl+C - it will be ignored ^C SIGINT ignored (use SIGTERM to terminate) Received SIGTERM - shutting down
Platform-Specific Signals
This example demonstrates platform-specific signal handling in 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)); }
We handle different signals based on the platform. Linux/macOS uses SIGUSR1, while Windows uses SIGBREAK. The code adapts to the current platform.
$ dart main.dart Running on linux Send platform-specific signals Received ProcessSignal_SIGUSR1
Best Practices
- Clean shutdown: Always perform cleanup in signal handlers
- Async handling: Use async/await for cleanup operations
- Platform awareness: Check signal availability per platform
- Signal documentation: Document expected signals in your app
Source
Dart ProcessSignal Documentation
This tutorial covered Dart's ProcessSignal class with practical examples showing signal handling, graceful shutdowns, and platform-specific considerations.
Author
List all Dart tutorials.