|
The trouble with your example is that the default for SIGINT is to terminate the program. You need to catch and ignore whatever signal you use to wake up the threads.
In the code below, SIGTERM is caught from the outside (so that 'kill PID' can be used). It then uses SIGUSR2 to wake up the threads.
#!/usr/bin/perl
use strict;
use warnings;
$| = 1;
use threads;
my ($thr1, $thr2, $term);
# SIGUSR2 is used to wake up threads
$SIG{USR2} = sub { print("Ignoring SIGUSR2\n"); };
$SIG{TERM} = sub {
print("Caught SIGTERM\n");
# Send signals to threads
print("Signalling thr1...\n");
$thr1->kill('USR1');
print("Signalling thr2...\n");
$thr2->kill('USR1');
print("Waking up threads using SIGUSR2...\n\n");
kill('USR2', $$);
$term = 1;
};
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");
$thr1 = threads->create('thr1');
$thr2 = threads->create('thr2');
$thr1->detach();
$thr2->detach();
sleep(1);
# Tell user what to do
print("\nWaiting for termination signals: kill $$\n\n");
# Wait for termination signal
while (! $term) { sleep(1); }
# Give threads a chance to finish
sleep(2);
}
print("\nDone\n");
exit(0);
You get output like:
Starting threads...
thr1 sleeping...
thr2 sleeping...
Waiting for termination signals: kill 21892
thr1 woke up
thr2 woke up
thr1 sleeping...
thr2 sleeping...
Caught SIGTERM
Signalling thr1...
Signalling thr2...
Waking up threads using SIGUSR2...
thr1 caught SIGUSR1
thr2 caught SIGUSR1
Ignoring SIGUSR2
thr1 woke up
thr2 woke up
thr1 done
thr2 done
Done
At any rate, you should be getting the idea by now. You'll just have to work with the details to get exactly what you need done.
|