Multithreading 如何在完成时使用Parallel::ForkManager重新启动子进程

Multithreading 如何在完成时使用Parallel::ForkManager重新启动子进程,multithreading,perl,loops,parallel-processing,fork,Multithreading,Perl,Loops,Parallel Processing,Fork,我希望让Parallel::ForkManager使用回调从子进程获取一些内容,然后重新启动它。可能吗?以下内容来自Parallel::ForkManager文档: use strict; use Parallel::ForkManager; my $max_procs = 5; my @names = qw( Fred Jim Lily Steve Jessica Bob Dave Christine Rico Sara ); # hash to resolve PID's back to

我希望让Parallel::ForkManager使用回调从子进程获取一些内容,然后重新启动它。可能吗?以下内容来自Parallel::ForkManager文档:

use strict;
use Parallel::ForkManager;

my $max_procs = 5;
my @names = qw( Fred Jim Lily Steve Jessica Bob Dave Christine Rico Sara );
# hash to resolve PID's back to child specific information

my $pm =  new Parallel::ForkManager($max_procs);

# Setup a callback for when a child finishes up so we can
# get it's exit code
$pm->run_on_finish(
  sub { my ($pid, $exit_code, $ident) = @_;
    print "** $ident just got out of the pool ".
      "with PID $pid and exit code: $exit_code\n";
  }
);

$pm->run_on_start(
  sub { my ($pid,$ident)=@_;
    print "** $ident started, pid: $pid\n";
  }
);

$pm->run_on_wait(
  sub {
    print "** Have to wait for one children ...\n"
  },
  0.5
);

foreach my $child ( 0 .. $#names ) {
  my $pid = $pm->start($names[$child]) and next;

  # This code is the child process
  print "This is $names[$child], Child number $child\n";
  sleep ( 2 * $child );
  print "$names[$child], Child $child is about to get out...\n";
  sleep 1;
  $pm->finish($child); # pass an exit code to finish
#####here is where I'd like each child process to restart
}

因此,当$pm->finish发生时,回调会确认“孩子”已“离开池”。我如何让回调启动,并在孩子出来时立即将其放回池中,使其永远运行?

我想你误解了发生的事情。在封面下,Parallel::ForkManager正在做的是调用
fork()
。此时存在两个过程,只有一个区别——不同的PID

您的子进程运行一些东西,然后退出,生成退出状态,然后您的父进程将获取该状态

正在重新启动进程。。。嗯,您只需要再次分叉并运行代码

现在,您正在做的是-一个foreach循环,即-foreach数组元素,fork,然后fork退出

所以说真的-你需要做的就是再次调用
$pm->start
。然而,如何确定哪个退出(以及子名称)更为困难——回调在父进程中运行,因此数据不会从子进程的退出状态传回。你需要找出某种IPC来通知必要的细节

尽管-我要指出
@names
不是散列,所以将其视为会有奇怪的行为:)


您是否考虑过线程作为替代方案?线程适合于共享内存操作,传递键控子进程是它擅长的事情

孩子不是用$ident传递回父母吗?我想我是通过将foreach更改为while(1),移动子对象,并将$ident推回到回调中的数组中来工作的。这应该可以做到——Parallel::ForkManager所做的主要工作是启动并限制活动的运行进程。不过要小心一点——模块文档没有明确说明何时触发回调——如果不小心(主代码中指令之间的数组更新),最终可能会在竞争条件下生成。