Perl signals
last modified October 20, 2026
A signal is a notification the operating system sends to a process, for example
when the user presses Ctrl-C or when a timer expires. Perl exposes signals
through the %SIG hash, where a key names the signal and the value is
a handler. The alarm function schedules an ALRM
signal, which makes it the usual way to add a timeout to a blocking operation.
Installing a handler for INT
Assigning a code reference to $SIG{INT} replaces the default
behaviour of terminating the program when Ctrl-C is pressed. The handler runs
between Perl operations, so it does not interrupt a statement in the middle.
#!/usr/bin/perl
use strict;
use warnings;
use v5.34.0;
local $SIG{INT} = sub { say "caught INT" };
kill 'INT', $$;
sleep 0;
say "after INT";
The program sends the INT signal to itself using kill
and the process ID stored in $$. Without the handler, the program
would stop at that point. With it, the handler prints a message and execution
continues. The sleep 0 gives Perl a moment to deliver the pending
signal before the next statement runs.
$ perl int_handler.pl caught INT after INT
Timeouts with alarm and eval
alarm sets a timer, in whole seconds, after which the process
receives ALRM. Combining it with eval is the common
pattern: the handler dies with a message, eval catches it, and the
program continues instead of hanging.
#!/usr/bin/perl
use strict;
use warnings;
use v5.34.0;
my $result = eval {
local $SIG{ALRM} = sub { die "timeout\n" };
alarm 1;
sleep 3;
alarm 0;
1;
};
say $result ? "finished" : "error: $@";
The sleep 3 stands in for a slow operation such as a network read.
After one second the alarm fires, the handler dies, and eval
returns false with the message in $@. The final alarm 0
cancels any pending alarm when the operation completes in time. The handler is
localized to the block so it does not leak into the rest of the program.
$ perl timeout.pl error: timeout
The message ends with a newline from die "timeout\n", and
say adds another, so the output shows an empty line after it.
Sending a signal with kill
kill sends a signal to a process. The first argument is the signal
name or number, and the rest are process IDs. Sending a signal with the signal
number 0 checks whether a process exists without affecting it.
#!/usr/bin/perl use strict; use warnings; use v5.34.0; say "own process alive: ", kill(0, $$) ? 1 : 0; my $gone = 999_999; say "absent pid alive: ", kill(0, $gone) ? 1 : 0;
Signal 0 performs the existence check only. kill returns the number
of processes it successfully signaled, so a true result means the process
exists and can receive signals. The PID 999999 is assumed unused, which is
typical but depends on the system.
$ perl kill_check.pl own process alive: 1 absent pid alive: 0
Best Practices
- Keep handlers short: set a flag and return, rather than doing heavy work inside the handler.
- Localize handlers: use
local $SIG{...}so the handler is restored when the block ends. - Always cancel alarms: call
alarm 0when the guarded operation finishes, so a late signal does not interrupt unrelated code. - Use eval for timeouts: a handler that dies with a message is the reliable way to escape a blocking call.
In this article we have covered %SIG handlers, timeouts with
alarm and eval, and sending signals with
kill.
Source
Author
List all Perl tutorials.