我有一个 perl 脚本,它向多个子进程发送大量输出。我需要能够关闭所有管道的末端,然后等待子流程完成它们的工作。到目前为止,我只成功地关闭了每个管道并等待每个子进程一个一个完成。更具体地说,我正在做这样的事情:
for ($i=0;$i<24;$i++) {
my $fh;
open $fh, "|externalprogram $i";
$fhs{$i}=$fh;
}
#...now I can write output to the pipes
while (moreworktodo()) {
$whichone, $data = do_some_work();
print $fhs{$whichone} $data;
}
#Now I just need to wait for all the subprocesses to finish. However, they
#need to do a lot of work that can only begin when they've finished reading input. So I need to close my end of the pipe to indicate I'm finished.
for ($i=0;$i<24;$i++) {
my $file = $fhs{$i};
close $file; #unfortunately, this blocks until process $i finishes
#meanwhile all the other processes are waiting for EOF
#on their STDIN before they can proceed. So I end up waiting
#for 24 processes to finish one-at-a-time instead of all at once
}
让所有子进程迅速完成(关闭它们的标准输入)的一种方法是让我的脚本退出而不关闭(管道)文件句柄,但这并不好,因为脚本是需要子进程的更大工作的一部分'在继续之前实际完成的工作。
关闭每个子进程的标准输入(以便它们都可以完成工作)然后等待所有子进程完成后再继续的简单方法是什么?我试过分叉一个孩子来关闭每个管道,但这似乎不起作用——只有父母的“关闭”实际上关闭了子进程的标准输入并等待子进程完成。