Threaded Pearls and Signal Handlers

I am using the Thread::Pool module in perl to parallelize some perl code. This process takes some time, and sometimes I will kill it from the command line using SIGINT . This causes the program to end abruptly, as I expected. This leaves some dirty temporary files, so I would like to install a signal handler. I have done this:

 sub INT_Handler{ #clean up code exit(1); } $SIG{'INT'} = 'INT_handler'; 

before creating the thread pool and starting the threads. Now, when I send SIGINT , workflows that are started, but the pool starts another set of work items to process the next set of jobs and continues to work. Why does the call to exit the signal handler not exit the main thread? What do I need to stop the process?

Edited in response to the comment of the mob

** Further editing **

Here is an example that I wrote.

 use Thread::Pool; sub INT_handler{ print "Handler\n"; exit(1); } $SIG{'INT'}='INT_handler'; sub f{ print "Started a thread " . rand(10000) . "\n"; sleep(10); } my $pool; my $submit = \&f; if (0){ $pool = Thread::Pool->new({do=>'f', workers=>5}); $submit = sub{ $pool->job; } } for (my $i = 0; $i < 100; $i++){ $submit->(); } $pool->shutdown if defined $pool; 

from 0 , I see the expected result

 h:57 Sep 15 16:15:19> perl tp.pl Started a thread 3224.83224635111 Handler 

but with 1 , this will happen

 h:57 Sep 15 16:14:56> perl tp.pl Started a thread 5034.63673711853 Started a thread 9300.99967009486 Started a thread 1394.45532885478 Started a thread 3356.0428193687 Started a thread 1424.4741558014 

etc., and the handler is not entered and the process continues to run. I had to kill the process with a signal other than SIGINT . Without a handler, both cases simply exit when SIGINT passed.

+3
source share
1 answer

This is more a hint than a final answer, but it looks like your main thread is never in a β€œsafe” state to trigger a signal handler. It works when you turn on unsafe Perl signals:

PERL_SIGNALS=unsafe perl tp.pl

For more information about safe and unsafe signals, see perlipc - perhaps this will lead you in the right direction to implement it with safe signals (as it should be).


(update from mob). Based on Michal's original understanding, this workaround with Perl::Unsafe::Signals also allows the handler to work as you expect.
 use Perl::Unsafe::Signals; ... UNSAFE_SIGNALS { $pool->shutdown if defined $pool; }; 

It’s so clear that this is a kind of secure Perl signaling mechanism that interferes with the signal on its way to the handler. I wonder if this will be fixed by placing the UNSAFE_SIGNALS { ... } block inside Thread::Pool::shutdown . In any case, I will write an error report about this.

+4
source

All Articles