加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl,Parallel :: ForkManager – 如何实现fork的超时

发布时间:2020-12-15 21:54:08 所属栏目:大数据 来源:网络整理
导读:是否可以使用Parallel :: ForkManager为fork实现某种超时(时间限制)? Basic Parallel :: ForkManager脚本如下所示 use Parallel::ForkManager;my $pm = Parallel::ForkManager-new( 10 );for ( 1 .. 1000 ) { $pm-start and next; # some job for fork $pm-
是否可以使用Parallel :: ForkManager为fork实现某种超时(时间限制)?

Basic Parallel :: ForkManager脚本如下所示

use Parallel::ForkManager;
my $pm = Parallel::ForkManager->new( 10 );
for ( 1 .. 1000 ) {
    $pm->start and next;
    # some job for fork
    $pm->finish;
}
$pm->wait_all_children();

我想限制“#for work for fork”的时间.例如,如果它没有在90秒内完成.然后它(fork)应该被杀死/终止.
我想到了using this,但我不得不说,我不知道如何在Parallel :: ForkManager中使用它.

编辑

谢谢hobbs和ikegami.你的建议都有效…..但只是在这个基本的例子中,而不是在我的实际脚本中:(.

这些叉子将永远存在 – 说实话 – 我不知道为什么.我使用这个脚本几个月.没有改变任何东西(虽然很多东西取决于外部变量).
每个fork都必须从网站下载页面,解析它并将结果保存到文件中.每叉不应超过30秒.超时设置为180秒.那些悬挂叉是完全随机的,因此很难追踪问题.这就是为什么我想出一个简单的临时解决方案 – 超时&杀.

什么可能在我的代码中禁用(中断)超时方法?我的代码中的任何地方都没有任何其他警报().

编辑2

其中一个分叉,悬挂1小时38分钟并返回“超时PID” – 这就是我在die()中输入的警报().所以超时工作…但它的晚期大约1小时36分钟;).你有什么想法?

解决方法

更新

很抱歉在收盘后更新,但如果我没有指出Parallel :: ForkManager也支持run_on_start回调,那将是我的疏忽.这可用于安装“子注册”功能,负责处理时间() – 为您标记PID.

例如.,

$pm->run_on_start(sub { my $pid = shift; $workers{$pid} = time(); });

结果是,如下所述,与run_on_wait一起,P :: FM的主循环不需要做任何特殊的事情.也就是说,它可以保持简单的$pm-> start和next,并且回调将处理其他所有事情.

原始答案

Parallel :: ForkManager的run_on_wait处理程序和一些记账,可以强制挂起和防止ALRM的孩子终止.

该函数注册的回调可以定期运行,而$pm等待终止子进程.

use strict; use warnings;
use Parallel::ForkManager;

use constant PATIENCE => 90; # seconds

our %workers;

sub dismiss_hung_workers {
  while (my ($pid,$started_at) = each %workers) {
    next unless time() - $started_at > PATIENCE;
    kill TERM => $pid;
    delete $workers{$pid};
  }
}

...

sub main {
  my $pm = Parallel::ForkManager->new(10);
  $pm->run_on_wait(&;dismiss_hung_workers,1);  # 1 second between callback invocations

  for (1 .. 1000) {
    if (my $pid = $pm->start) {
      $workers{$pid} = time();
      next;
    }
    # Here we are child.  Do some work.
    # (Maybe install a $SIG{TERM} handler for graceful shutdown!)
    ...
    $pm->finish;
  }

  $pm->wait_all_children;

}

(正如其他人所说,最好让孩子通过警报来调节自己(),但这似乎对你来说是间歇性的不可行的.你也可以采取浪费,粗暴的行为,例如让每个孩子自己分叉()或执行(‘bash’,‘-c’,’睡90;杀死-TERM $PPID’).)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读