将子进程中执行的进程的值返回给父进程

时间:2013-03-04 15:55:52

标签: perl fork

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

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
}    

任何帮助都会很棒。

3 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:4)

Forks::Superbg_evalbg_qx方法是为了解决这个问题。

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]将填充结果。

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

答案 2 :(得分:1)

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

另请参阅关于perlmonks的this帖子,了解为何需要锁定变量。