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を使用して、finishメソッドのdata_structure_referenceパラメーターを介して子から親のrun_on_finishコールバックに値を返すことができます。

出力をキャプチャする最も簡単な方法は、IPC :: System::Simpleのcaptureまたはcapturexを使用することです。

于 2013-03-04T16:13:38.380 に答える
4

bg_evalとのbg_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]に結果が入力されます。

印刷する$result[$_]と、次の2つのいずれかが発生します。その変数に関連付けられているバックグラウンドプロセスが終了すると、その変数に戻り値が含まれます。バックグラウンドプロセスが終了していない場合は、プロセスが終了するのを待ってから、その値で戻り値を使用できるようにします。

于 2013-03-04T17:01:50.640 に答える
1

forkの代わりにthreads::sharedを使用し、共有変数を作成し、それをロックして書き込みます。ロックは非常に遅いことに注意してください!

変数のロックが必要な理由については、perlmonksに関するこの投稿も参照してください。

于 2013-03-04T16:09:41.527 に答える