【发布时间】:2011-11-18 03:07:37
【问题描述】:
我在 perl 中使用 Thread::Pool 模块来并行化一些 perl 代码。这个过程需要一段时间,有时我会从命令行使用SIGINT 将其终止。正如我所料,这样做会导致程序突然结束。这留下了一些混乱的临时文件,所以我想安装一个信号处理程序。我这样做了:
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
etc 并且处理程序没有被输入并且进程继续运行。我不得不用SIGINT 以外的信号终止进程。如果没有处理程序,两种情况都会在传递 SIGINT 时简单地退出。
【问题讨论】:
-
这与the documentation 存在争议:“信号被脚本的主线程(线程 ID = 0)捕获。”你能隔离并发布一些信号似乎被工作线程捕获的代码吗?
-
@mob 好的,所以我一定是误认为信号被工人捕获了。我认为是这种情况,因为我在信号处理程序中明确调用了 exit。然而,我观察到的是正在运行的工作线程和一组新的工作线程正在启动。
标签: multithreading perl signal-handling