|
As documented in the POD, the signals sent using
$thr->kill() do not interrupt activities within the
thread. If the thread is sleeping, it will only see the
signal after the sleep call finishes, or if something
interrupts the sleep call. As such, thread signalling is
primarily useful for communication, and not that good for
control.
However, you could use a regular signal to break the sleeps
inside threads after you send them whatever signal you need:
#!/usr/bin/perl
use strict;
use warnings;
$| = 1;
use threads;
# SIGINT is used to wake up threads
$SIG{INT} = sub { print("Ignoring SIGINT\n"); };
sub thr1
{
my $term = 0;
$SIG{USR1} = sub {
print("\tthr1 caught SIGUSR1\n");
$term = 1;
};
while (! $term) {
print("\tthr1 sleeping...\n");
sleep 100;
print("\tthr1 woke up\n");
}
print("\tthr1 done\n");
}
sub thr2
{
my $term = 0;
$SIG{USR1} = sub {
print("\t\tthr2 caught SIGUSR1\n");
$term = 1;
};
while (! $term) {
print("\t\tthr2 sleeping...\n");
sleep 100;
print("\t\tthr2 woke up\n");
}
print("\t\tthr2 done\n");
}
MAIN:
{
print("Starting threads...\n");
my $thr1 = threads->create('thr1');
my $thr2 = threads->create('thr2');
$thr1->detach();
$thr2->detach();
sleep(1);
print("\nSignalling thr1...\n");
$thr1->kill('USR1');
sleep(1);
print("Waking up threads...\n");
kill('INT', $$);
sleep(1);
print("\nSignalling thr2...\n");
$thr2->kill('USR1');
sleep(1);
print("Waking up threads...\n");
kill('INT', $$);
sleep(2);
}
print("\nDone\n");
exit(0);
This produces:
Starting threads...
thr1 sleeping...
thr2 sleeping...
Signalling thr1...
Waking up threads...
thr2 woke up
thr2 sleeping...
thr1 caught SIGUSR1
thr1 woke up
Ignoring SIGINT
thr1 done
Signalling thr2...
Waking up threads...
thr2 caught SIGUSR1
Ignoring SIGINT
thr2 woke up
thr2 done
Done
You'll have to try this yourself as there may be system
dependency issues with signals.
|