我在perl中使用了Thread::Pool
模塊來並行化一些perl代碼。這個過程需要一段時間,偶爾我會用SIGINT
從命令行中終止它。正如我所料,這樣做會導致程序突然結束。這留下了一些凌亂的臨時文件,所以我想安裝一個信號處理程序。我這樣做:螺紋perl和信號處理程序
sub INT_Handler{
#clean up code
exit(1);
}
$SIG{'INT'} = 'INT_handler';
在創建線程池和啓動線程之前。現在,當我發送正在運行的SIGINT
,worker threads,但池會立即啓動另一組工作人員處理下一組作業並繼續運行。爲什麼在信號處理程序中退出的調用不會退出主線程?我需要什麼來阻止該進程運行?
編輯響應暴民的評論
**進一步編輯**
這裏是我寫了一個例子。
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;
與0
,我看到預期的結果
h:57 Sep 15 16:15:19> perl tp.pl
Started a thread 3224.83224635111
Handler
但1
,出現這種情況
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
等和處理程序沒有得到進入和進程繼續運行。我不得不用SIGINT
以外的信號殺死進程。如果沒有處理程序,這兩種情況都會在通過SIGINT
時退出。
這與[文檔]爭論(http://search.cpan.org/perldoc?threads#BUGS_AND_LIMITATIONS):「腳本的主線程(線程ID = 0)捕獲*信號。 「你能隔離併發布一些代碼,這些代碼在工作線程中似乎被捕獲到了嗎? – mob
@mob好的,所以我必須誤認爲信號被工作人員抓住了。我認爲是這樣,因爲我明確地在信號處理程序中調用exit。然而,我觀察到的是正在運行的工作者線程以及正在啓動的一組新工人。 –