2

我正在寻找一种解决方案,它允许我将在子进程中执行的进程的值返回给父进程。目前我尝试这个但不知道在哪里挂钩返回值:

use Proc::ProcessTable;
use POSIX qw(:signal_h :errno_h :sys_wait_h);
$SIG{CHLD} = \&REAPER;

for my $count (1..10) {  # start a few demo childs
 if (fork () == 0) {
  &startChild;
  exit 0;
 }     
}

do  {
 print "Working\n";
 sleep 1;
} while (chkChildProcess());

sub startChild {
  print "Starting Child $$\n";
  system("date"); #==>Need to get the output of "date" back to parent
  sleep 2 + rand 7; 
  print "End  Child $$\n";
}

sub chkChildProcess {
 for my $p (@{new Proc::ProcessTable->table}){
  if ($p->ppid == $$){
   $curPID{$$}=$p->pid;
   return 1;
  }
 }
 return undef;
}


sub REAPER {
my $pid;
$pid = waitpid(-1, &WNOHANG);
if ($pid == -1) {
 # no child waiting.  Ignore it.
} elsif (WIFEXITED($?)) {
 print "Process $pid exited.\n";
} else {
 print "False alarm on $pid.\n";
}
$SIG{CHLD} = \&REAPER;          # in case of unreliable signals
}    

任何帮助都会很棒。

4

3 回答 3

4

看起来您可能想要使用Parallel::ForkManager,通过完成方法的 data_structure_reference 参数从子级返回值到父级中的 run_on_finish 回调。

要捕获输出,最简单的方法是使用IPC::System::Simple的 capture 或 capturex。

于 2013-03-04T16:13:38.380 回答
4

为解决这个问题而提出的bg_evalbg_qx方法。Forks::Super

use Forks::Super 'bg_eval';

my @result;
for my $count (1 .. 10) {

    $result[$count] = bg_eval {
        my $date = `date`;
        sleep 2 + rand 7;
        return $date;
    };
}

print "$result[$_]\n" for 1..10;

之后的块在bg_eval后台进程中异步运行。后台进程完成后,变量$result[$count]将填充结果。

当您 print$result[$_]时,会发生以下两种情况之一。如果与该变量关联的后台进程完成,它将包含其返回值。如果后台进程没有完成,它将等待进程完成,然后在该值中提供返回值。

于 2013-03-04T17:01:50.640 回答
1

你可以使用threads::shared而不是fork,创建一个共享变量,锁定它并写入它。请记住,锁定非常慢!

另请参阅perlmonks 上的这篇文章,了解为什么需要锁定变量。

于 2013-03-04T16:09:41.527 回答