2014-11-08 32 views
0

我想让Parallel :: ForkManager使用回调从子进程中取回某些内容,然后重新启动它。那可能吗?以下是从平行:: 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)[email protected]_; 
    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 
} 

所以当$ - 下午>完成情况,回调确认的“孩子”是“出池。”我怎样才能让回火起火,并立即将孩子放回池中,以便它永远运行下去?

回答

1

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

你的子进程会运行一些东西,然后退出,产生一个退出状态,然后你的父母收回。

重新启动过程......好吧,您只需再次分叉并运行代码。

现在,你在做什么 - 一个foreach循环,foreach数组元素,叉,然后叉退出。

真的 - 所有您需要做的,就是再次拨打$pm -> start。如何确定哪一个退出(因此儿童名称)更困难 - 您的回调在父进程中运行,因此数据不会从您孩子的退出状态回传。你需要找出某种IPC来通知必要的细节。

虽然 - 我指出@names不是一个散列,所以对待它像一个会有奇怪的行为:)。

你是否认为线程是一种替代方法?线程对于共享内存操作是很好的,传递键控子进程是它擅长的。

+0

是不是孩子通过$ ident传回给父母?我认为我通过改变foreach的方式来工作,同时(1),转移孩子,并将$ ident推回到回调数组中。 – user2387065 2014-11-08 21:54:49

+0

这应该做到这一点 - Parallel :: ForkManager所做的主要事情是启动并限制活动的运行进程。尽管要小心一点 - 模块文档没有清楚地说明何时回调被触发 - 您可能最终在竞争条件下构建您不小心(主代码中的指令之间的数组更新)。 – Sobrique 2014-11-08 22:27:46

相关问题