Control + C in multi-threaded perl script
I am new to perl and I have a problem handling ^ C in my perl script. When I try to continue executing the script after receiving ^ C while sleeping, I only have an output until $ FLAG = 2; and nothing after:
# perl test.pl
sleeping...
^Cawaiking... =
#
instead:
# perl test.pl
sleeping...
awaiking... ====
some..
#
This causes ^ C to kill the stream of progressive bars and after it doesn't kill any action, but printing can be done on the main thread. Can anyone help me with this problem?
$SIG{INT} = 'IGNORE';
our $FLAG : shared = 1;
...
sub call1{
$FLAG = 1;
my $pBar = threads->new(\&progressBarInit);
$pBar->detach;
print "sleeping...\n";
sleep 5;
print "awaiking...\n";
$FLAG = 2;
print "some..\n";
return @result;
}
call1();
sub progressBarInit{
my $max = 50;
my $counter = 1;
while($FLAG == 1){
progressBar( $counter, $max, 50, '=' );
$counter++;
if($counter > $max){$counter=1;}
sleep 1;
}
}
sub progressBar {
my ( $counter, $max, $width, $char ) = @_;
local $| = 1;
printf " %-${width}s\r", $char x (($width-1)*$counter/$max);
}
+3
source to share
1 answer
I think the problem is that you are setting up a signal handler in the parent.
According to this: http://perldoc.perl.org/threads.html
Signal handlers must be configured in streams for signals to which they must respond. Here's an example of canceling a stream:
Instead of using a flag, you can use signals to communicate:
sub progressBarInit {
# Thread 'cancellation' signal handler
$SIG{'KILL'} = sub { threads->exit(); };
$SIG{INT} = 'IGNORE';
...
}
...
# Signal the thread to terminate, and then detach
# it so that it will get cleaned up automatically
my $pBar = threads->new(\&progressBarInit);
print "sleeping...\n";
sleep 5;
print "awaiking...\n";
$pBar->kill('KILL')->detach();
0
source to share