线程化的Perl和信号处理程序 [英] Threaded perl and signal handlers

查看:74
本文介绍了线程化的Perl和信号处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Thread::Pool 模块以并行化一些perl代码.此过程需要一段时间,有时我会在命令行中使用 SIGINT .如我所料,这样做会使程序突然结束.这会留下一些混乱的临时文件,因此我想安装一个信号处理程序.我是这样做的:

I am using the Thread::Pool module in perl to parallelize some perl code. This process takes a while and occasionally I will kill it from the command line with a SIGINT. Doing so causes the program to end abruptly, as I expected. This leaves some messy temporary files around, so I'd like to install a signal handler. I did this:

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

在创建线程池和启动线程之前.现在,当我发送 SIGINT 时,

before creating the thread pool and starting the threads. Now when I send the SIGINT, the worker threads that are running die, but the pool promptly launches another set workers to handle the next set of jobs and continues running. Why doesn't the call to exit in the signal handler exit the main thread? What do I need to stop the process from running?

根据mob的评论进行了编辑

**进一步编辑**

** Further edit **

这是我写的一个例子.

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,我看到了预期的结果

with 0, I see the expected result

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

但使用1时,会发生这种情况

but with 1, this happens

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 时,这两种情况都将简单退出.

etc and the handler doesn't get entered and the process continues running. I had to kill the process with a signal other than SIGINT. Without the handler, both cases simply exit when passed a SIGINT.

推荐答案

这只是一个提示,而不是一个确定的答案,但是看来您的主线程永远不会处于运行信号处理程序的安全"状态.当启用Perl的不安全信号时,它确实起作用:

This is more a hint rather than a definitive answer, but it appears your main thread is never in the "safe" state to run the signal handler. It does work when you enable Perl's unsafe signals:

PERL_SIGNALS=unsafe perl tp.pl

有关安全和不安全信号的详细信息,请参见 perlipc 也许它将引导您朝正确的方向以安全信号实施它(可能应该如此).

See perlipc for more information on safe and unsafe signals -- maybe it will lead you in the right direction to implement it with safe signals (as it probably should be).


(由暴民更新)基于Michal的原始见解,此变通办法与


(update by mob) Building on Michal's original insight, this workaround with Perl::Unsafe::Signals also gets the handler to work as you'd expect

use Perl::Unsafe::Signals;
...
UNSAFE_SIGNALS {
    $pool->shutdown if defined $pool;
};

因此,很明显,Perl的安全信号机制与正在传送到处理程序的信号有关.我想知道是否可以通过在Thread::Pool::shutdown内放置一个UNSAFE_SIGNALS { ... }块来解决此问题.无论哪种方式,我都会提交有关此问题的错误报告

So clearly it is something about Perl's safe signalling mechanism that is interfering with the signal on its way to the handler. I wonder if this would be fixed by putting an UNSAFE_SIGNALS { ... } block inside of Thread::Pool::shutdown. Either way, I would file a bug report about this.

这篇关于线程化的Perl和信号处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆