Beefy Boxes and Bandwidth Generously Provided by pair Networks Cowboy Neal with Hat
go ahead... be a heretic
 
PerlMonks  

Catching signals under Linux

by weismat (Friar)
on Jan 29, 2010 at 07:49 UTC ( #820318=perlquestion: print w/ replies, xml ) Need Help??
weismat has asked for the wisdom of the Perl Monks concerning the following question:

I am having trouble that my script should change a shared variable based on a signal. The signal is caught and the shared variable is changed, but the program does automatically stop. See below some a small piece of code as an example. I am using Perl 5.10.0 and CentOS 4.
use threads; use threads::shared; $SIG{'HUP'}='switchFlag'; $flag::shared; my $thr=threads->new(\&printer); $thr->detach(); sleep 10000; print "I am here\n"; exit; sub printer{ while(1) { sleep 1; print "Shared: $flag\n"; } } sub switchFlag{ $flag=!$flag; print "signal caught"; $SIG{'HUP'}='switchFlag'; }
Update: Same behaviour with Perl 5.8 under Solaris 10...

Comment on Catching signals under Linux
Download Code
Re: Catching signals under Linux
by Anonymous Monk on Jan 29, 2010 at 07:58 UTC
    Which thread caught the signal? Did that thread end?
      I can not really tell, but my guess is that it is the main thread...
        Um, guessing is not allowed :D
        #!/usr/bin/perl -- use strict; use warnings; use threads; use threads::shared; Main(@ARGV); exit(0); sub Main { local $SIG{'HUP'} = 'switchFlag'; share($::flag); $::flag = !!undef; # false my $thr = threads->new( \&printer ); $thr->detach(); sleep 10000; print threads->tid, " is here\n"; } ## end sub Main sub printer { while (1) { sleep 1; print threads->tid, " Shared: $::flag\n"; } } ## end sub printer sub switchFlag { $::flag = !$::flag; print threads->tid, " caught signal\n"; $SIG{'HUP'} = 'switchFlag'; }
Re: Catching signals under Linux
by 7stud (Deacon) on Jan 29, 2010 at 10:06 UTC

    On a more elementary level, why does this code:

    use strict; use warnings; use 5.010; use threads; sub thr_func { say 'in thread'; $SIG{'HUP'} = sub { say "signal caught" }; } my $thr = threads->create('thr_func'); $thr->kill('HUP')->join();
    produce this output:
    Signal SIGHUP received, but no signal handler set.

    The threads docs seem pretty clear that you can signal a thread.

      Because you're likely to send the signal before the other thread was able to set the handler. Note that your output doesn't include 'in thread', which is printed before you set SIGHUP.
        Yup:
        use strict; use warnings; use 5.010; use threads; sub thr_func { say 'in thread'; $SIG{'HUP'} = sub { say "signal caught" }; say 'doing some task...'; sleep 5; } my $thr = threads->create('thr_func'); sleep 2; $thr->kill('HUP')->join(); --output:-- in thread doing some task... signal caught
        Thanks.

        I have not looked closely at your code, but I would observe that the scenario just described is extremely common, and therefore extremely likely.

Re: Catching signals under Linux
by dave_the_m (Parson) on Jan 29, 2010 at 16:59 UTC
    You have two issues. First, by $flag::shared;, I think you actually meant my $flag : shared;; i.e. you weren't actually creating a shared variable.

    Second, if the signal gets delivered to the parent thread, then that will wake it up from its sleep, so you'll want something like sleep 10000 while 1 to keep it alive.

    Dave.

Re: Catching signals under Linux
by 7stud (Deacon) on Jan 29, 2010 at 21:32 UTC

    Is this what you want?

    use strict; use warnings; use 5.010; use threads; use threads::shared; my $flag = 0; share($flag); say "\$flag in main() is: $flag"; $SIG{'HUP'} = sub { $flag = !$flag; say "signal caught, \$flag in main() changed to: $flag"; }; sub thr_func { for (1 .. 5) { sleep 1; say "\$flag in thread is: $flag"; } } my $thr = threads->create('thr_func')->detach(); sleep 3; #allow time for thread to be created and start running kill('HUP', $$); #send signal to main() sleep 10; --output:-- $flag in main() is: 0 $flag in thread is: 0 signal caught, $flag in main() changed to: 1 $flag in thread is: 0 $flag in thread is: 1 $flag in thread is: 1 $flag in thread is: 1

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://820318]
Approved by planetscape
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (8)
As of 2014-04-19 01:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (475 votes), past polls