我正在寻找一种解决方案,它允许我将子进程中执行的进程的值返回给父进程。目前我尝试这个但不知道在哪里挂钩返回值:
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
}
任何帮助都会很棒。
答案 0 :(得分:4)
看起来您可能想要使用Parallel::ForkManager,通过finish方法的data_structure_reference参数将子值返回到父级中的run_on_finish回调。
要捕获输出,最简单的方法是使用IPC::System::Simple的捕获或捕获x。
答案 1 :(得分:4)
Forks::Super
的bg_eval
和bg_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帖子,了解为何需要锁定变量。