Dart ProcessSignal tutorial shows how to handle process signals in Dart using the ProcessSignal class.
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).
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.
This example shows basic SIGINT (Ctrl+C) signal handling in Dart.
main.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…
This example demonstrates handling multiple signals with one listener.
main.dart
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
This example implements a graceful shutdown with cleanup operations.
main.dart
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
This example shows how to ignore certain signals in your application.
main.dart
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
This example demonstrates platform-specific signal handling in Dart.
main.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
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
Dart ProcessSignal Documentation
This tutorial covered Dart’s ProcessSignal class with practical examples showing signal handling, graceful shutdowns, and platform-specific considerations.
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all Dart tutorials.