Since you haven't shown your code for how you're handling the signals, I can only hazard a guess. The OS SIGUSR1 comes to each child process' main thread (because that's how it works). Then the child process in turn does a $thread->kill() on each of your threads. So far so good?

See threads:

sending a signal to a thread does not disrupt the operation the thread is currently working on: The signal will be acted upon after the current operation has completed. For instance, if the thread is stuck on an I/O call, sending it a signal will not cause the I/O call to be interrupted such that the signal is acted up immediately.

The good news is, there's a simple answer to the question of how to send signals to threads: don't. It's unreliable at best, and even if it worked, your threads would be in random states. Instead, instrument your threads with their own timeouts (if they're doing blocking operations, that's really where the timeouts belong anyway), and have the threads poll a threads::shared $shutdown variable that's set by your signal handler. Provided you have reasonable timeouts and don't just busy-wait, this is a reasonable use of polling. With the above caveat, remember your child program's main application flow is a thread, too, and subject to the same limitations. When the signal comes in, you give all the threads a few seconds to exit, and if there are still any running, you detach them and exit with a warning.

bash $ (sleep 1; killall -HUP the_parent) & perl threads.pl [1] 4842 Thread 1: Created Thread 2: Created Thread 3: Created Shutting down 3 threads Thread 1: Shutting down Thread 3: Shutting down 1 still running. Giving up!
#!/usr/bin/env perl use 5.012; use warnings FATAL => 'all'; use autodie; if (my $pid = fork) { $0 = 'the_parent'; local $SIG{HUP} = sub { kill USR1 => $pid }; exit(0 < waitpid $pid,0); } $0 = 'the_child'; use threads; use threads::shared; my $shutdown :shared = 0; my @thr = map { threads->create(sub { printf "Thread %d: Created\n", threads->tid; sleep 1 + rand 2 until $shutdown; printf "Thread %d: Shutting down\n", threads->tid; lock($shutdown); cond_signal($shutdown); }) } 1..3; $SIG{USR1} = sub { $shutdown = 1 }; sleep until $shutdown; say "Shutting down " . scalar threads->list . " threads"; my $until = 1 + time; # Wait this many seconds before abort while (my $threads = threads->list(threads::running)) { lock($shutdown); cond_timedwait($shutdown, $until) or last; } if (my @remain = threads->list(threads::running)) { $_->detach for @remain; $_->join for threads->list(threads::joinable); die scalar @remain . " still running. Giving up!\n"; } $_->join for @thr; say "All threads exited normally.";

In reply to Re: killing threads inside forks by rjt
in thread killing threads inside forks by mojo2405

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.