【问题标题】:ForkManager SIGINT only kills current process in forkForkManager SIGINT 只杀死 fork 中的当前进程
【发布时间】:2015-07-07 20:00:49
【问题描述】:

当我杀死一个使用 ForkManager 的 perl 进程时,我希望所有子进程都死掉。在下面的代码中,如果我运行它并在 sleep 行运行时按 ctrl+c ,则 sleep 进程被终止,但 print 行都是在脚本结束之前同时执行。理想情况下,我希望中断立即停止所有执行。我能做什么?

#!/usr/bin/perl -w
use Parallel::ForkManager;

main {
    my $fork1 = new Parallel::ForkManager(8);
    while (1) {
        $fork1->start and next;
        system("sleep 15s");
        print "Still going!"
        $fork1->finish;
    }
    fork1->wait_all_children;
}

【问题讨论】:

  • system 也分叉了一个进程,我想如果你将 system("sleep 15s") 更改为 Perl 的 sleep 15; 你不会看到同样的行为。

标签: perl parallel-processing fork


【解决方案1】:

根据perldoc systemsystem 实际上忽略了 SIGINT 和 SIGQUIT:

由于 SIGINT 和 SIGQUIT 在系统执行期间被忽略, 如果您希望您的程序在收到这些信号时终止 您需要根据返回值自行安排。

因此,如果您希望您的进程在system 调用期间停止执行 SIGINT,您需要自己实现该逻辑:

#!/usr/bin/perl -w
use Parallel::ForkManager;

main {
   my $fork1 = new Parallel::ForkManager(8);
   while (1) {
      $fork1->start and next;
      print "Sleeping...";
      system("sleep 15s") == 0 or exit($?);
      print "Still going!";
      $fork1->finish;
   }
   fork1->wait_all_children;
}

或者更合理的方法是使用Perl内置的sleep

#!/usr/bin/perl -w
use Parallel::ForkManager;

main {
   my $fork1 = new Parallel::ForkManager(8);
   while (1) {
      $fork1->start and next;
      print "Sleeping...";
      sleep 15;
      print "Still going!";
      $fork1->finish;
   }
   fork1->wait_all_children;
}

【讨论】:

  • 太棒了!我没有意识到系统正在拦截 SIGINT。 (而使用 system() 的原因是这只是许多非睡眠系统命令的一个示例......)
【解决方案2】:

首先 - 使用system 意味着你可能会发生一些奇怪的事情,因为......然后你允许你调用的任何东西自己处理信号。

这可能是你的问题。

但除此之外,您可以使用 perl 执行的操作是配置信号处理程序 - 如果此进程收到信号时该怎么办。默认情况下 - 信号设置为“退出”或“忽略”。

您可以通过print Dumper \%SIG;查看当前的情况

但是,我认为解决问题的最简单方法是设置一个处理程序来捕获SIGINT,然后将kill 发送到您当前的进程组。

当 PROCESS 编号为零或负数时,kill 的行为取决于操作系统。例如,在符合 POSIX 的系统上,零表示当前进程组,-1 表示所有进程,任何其他负的 PROCESS 编号将充当负信号编号并终止指定的整个进程组。

$SIG{'INT'} = sub { 
    kill ( 'TERM', -$$ );
};

【讨论】:

    猜你喜欢
    • 2020-04-13
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    相关资源
    最近更新 更多