Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, a mum.pl using
threads; threads::shared;
detaches her childs:
our $D = threads->new(\&Darling::run, ID => 'Darling' ); $D->detach(); ... while (my $client = $server->accept()) { #foreach $client my $pAddr = $client->peerhost(); ... }
Well mum.pl catches the SIGNALS like
$SIG{KILL} = 'mumsDeath'; $SIG{TERM} = 'mumsDeath'; sub mumsDeath {$D->kill('KILL'); print "killing my darling\n";}
But now I want Darling to die gracefully and I need to catch mums SIGNAL within Darling (by Darlin)!
But for what ever reason Darlings dies silently, without any cry?
Does anybody may give me hint how Darling can catch mum's bullet to die gracefully with a little sigh?
Thanks a lot in advance!!
package Darling; use threads; use threads::shared; our $minID; sub new { #: create Darling my $pkg = shift; my $self = { @_ }; return bless($self, $pkg); ##: arr of blessed (self, pkg) } sub catchBullet { print "\n\n$0 :: $minID SIGNAL caught !!\n"; } sub run { my $self = MinBar->new(@_); #: Me $minID = $self->{ID}; #: $|++; $SIG{TSTP} = 'catchBullet'; $SIG{INT} = 'catchBullet'; $SIG{TERM} = 'catchBullet'; $SIG{KILL} = 'catchBullet'; $SIG{QUIT} = 'catchBullet'; $SIG{STOP} = 'catchBullet'; $SIG{USR2} = 'catchBullet'; $SIG{USR1} = 'catchBullet'; print "$0 :: $minID starting: "; while ( 1 ) { sleep 30; print "." } }
Carl

Replies are listed 'Best First'.
Re: Gracefull Death of a Child: How to Catch Mum's SIGNALS?
by Fletch (Bishop) on Apr 03, 2007 at 18:55 UTC

    Erm not that I've done much with threads, but:

    • I'm fairly sure that signals are sent and received at a process level, not thread level (not to mention that perlthrtut warns against mixing signals and threads)
    • That aside, SIGKILL is uncatchable; the receiving process is terminated and removed from the process table and it's never delivered (so assigning a handler for it is kinda superfluous)

    (Of course having said that I'd be interested to find out one way or another about what happens with signals under threads.)

Re: Gracefull Death of a Child: How to Catch Mum's SIGNALS?
by Moron (Curate) on Apr 03, 2007 at 18:17 UTC
    I can think of a few, but the first that comes to mind is sigtrap.

    Update: I think on reflection it would be better however, given the threaded environment, to send and catch your own type of "signals" using Thread::Queue

    -M

    Free your mind

Re: Gracefull Death of a Child: How to Catch Mum's SIGNALS?
by gt8073a (Hermit) on Apr 03, 2007 at 19:16 UTC

    I need to catch mums SIGNAL within Darling (by Darlin)
    Oops, I read that totally wrong.

    A cheap trick to see what signal is getting caught, try this:
    $SIG{$_} = sub { print "$$: Caught \$SIG{$_}\n" } for ( keys %SIG );

    JJ
      well,
      using within Mum 'Mum' and Darling 'Dar'
      for my $k ( keys %SIG ) { $SIG{$k} = sub { print "\n$$: 'Mum' Caught \$SIG{ $k }\n" } }
      and killing mum.pl by her pid by USR1 - but any other SIG does the same:
      kill -USR1 7405
      I get mum's sigh
      7405: 'Mum' Caught $SIG{ USR1 }
      but Darling still dies silently ;(


      If (me, playing around) Mum and Darling use 'local':

      for my $k ( keys %SIG ) { local $SIG{$k} = sub { print "\n$$: Mum Caught \$SIG{ $k }\n" } }
      Only Mum doesn't catch any SIG anymore, I just get
      userdefined Signal 1
      (in german) :(
      Even the use of sigtrap within Darling makes no difference..
      Thanks anayway ..
      Carl

        As others have mentioned, threads are in a single process. So killing mum is killing darling. They're the same process, different thread.

        In the code below, $SIG{$k} is local to the for block.

        for my $k ( keys %SIG ) { local $SIG{$k} = sub { print "\n$$: Mum Caught \$SIG{ $k }\n" } }

        For your own experience, try removing %SIG handlers from mum, and only put them in darling. Also, compare fork() to your threads.

        JJ
        oh ok! re "use sigtrap makes no difference" - well it wouldn't unless you define a handler for the signal being sent.

        Update: what about using Thread::Queue to send and receive homegrown "signals" - that way at least you have some guarantee of thread safety.

        -M

        Free your mind

Re: Gracefull Death of a Child: How to Catch Mum's SIGNALS?
by gt8073a (Hermit) on Apr 03, 2007 at 18:49 UTC
    I think the signal you want to trap in Darling is HUP.
    JJ
      I think he intends to send a SIGKILL: $D->kill('KILL') ...

      The thing I wonder about is the signals themselves. When I think of signal handlers and things, I usually think of fork not threads... I'm very bad at threads so far though, so I could be wrong about that.

      It would seem that the thread method $thrd->kill() sends a signal to the one thread. In all their examples, they use $thrd->kill("KILL")->detach (for cleanup); and the parent poster detaches before signaling. It makes me wonder if you can even do that... But, again, I don't really know.

      update: oh, duh, you can't catch the 9th signal... way to go fletch.

      -Paul

        I usually think of fork not threads... I'm very bad at threads so far

        Tip. Don't even consider trying to use signals in conjunction with threads. Signals are an inter-process mechanism. All your threads are part of the same, single process.

        Whilst there may be some platforms out there that have adapted their threading and signalling libraries to work together in some non-standard but successful way, Perl's threading is not be coded to use those facilities, and probably never will.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.