T
Tom
I've got a multithreaded script in which I'd like to have my "worker"
threads ignore SIGINT (i.e. the main thread traps it and calls a sub to
cleanup nicely after all workers are done). The workers do their thing
via system() calls, and my experience (using 5.8.8 at least) indicates
that SIGINT is being propogated to the worker threads' system() call
(even though it's locally ignored).
According to perlfaq8, system() is shielded from SIGINT:
-----------------------------------------------------------------------------
How do I make a system() exit on control-C?
You can't. You need to imitate the system() call (see perlipc for
sample code) and then have a signal handler for the INT signal that
passes the signal on to the subprocess.
-----------------------------------------------------------------------------
When CTRL-C is hit on the console, the following code will print
"Cleaning up..." and exits promptly. I would have expected it to exit
after all threads have returned.
#!/usr/bin/perl -w
use strict;
use threads;
$SIG{INT} = \&cleanup;
foreach my $id ( 1..10 ) {
threads->new( \&sleeper, $id );
}
sleep 60;
sub cleanup {
print "Cleaning up\n";
foreach my $thread ( threads->list() ) {
$thread->join();
}
exit();
}
sub sleeper {
my $id = shift;
my $time = int( rand(30) );
local $SIG{INT} = 'IGNORE';
print "Thread $id sleeping for $time...\n";
system( "sleep $time" );
return;
}
threads ignore SIGINT (i.e. the main thread traps it and calls a sub to
cleanup nicely after all workers are done). The workers do their thing
via system() calls, and my experience (using 5.8.8 at least) indicates
that SIGINT is being propogated to the worker threads' system() call
(even though it's locally ignored).
According to perlfaq8, system() is shielded from SIGINT:
-----------------------------------------------------------------------------
How do I make a system() exit on control-C?
You can't. You need to imitate the system() call (see perlipc for
sample code) and then have a signal handler for the INT signal that
passes the signal on to the subprocess.
-----------------------------------------------------------------------------
When CTRL-C is hit on the console, the following code will print
"Cleaning up..." and exits promptly. I would have expected it to exit
after all threads have returned.
#!/usr/bin/perl -w
use strict;
use threads;
$SIG{INT} = \&cleanup;
foreach my $id ( 1..10 ) {
threads->new( \&sleeper, $id );
}
sleep 60;
sub cleanup {
print "Cleaning up\n";
foreach my $thread ( threads->list() ) {
$thread->join();
}
exit();
}
sub sleeper {
my $id = shift;
my $time = int( rand(30) );
local $SIG{INT} = 'IGNORE';
print "Thread $id sleeping for $time...\n";
system( "sleep $time" );
return;
}