ZetCode

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.

int_handler.pl
#!/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.

timeout.pl
#!/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.

kill_check.pl
#!/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

In this article we have covered %SIG handlers, timeouts with alarm and eval, and sending signals with kill.

Source

perlipc: Signals ยท alarm

Author

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 Perl tutorials.