use strict;
use warnings;
use Parallel::ForkManager;
my $log = "/scripts/downloads/test.log";
print "Check the $log file\n" and open(LOG,">$log");
*STDERR = *LOG;
*STDOUT = *LOG;
my $pmm=new Parallel::ForkManager(9);
my @arr=(1..200);
for(@arr){
$pmm->start and next; # do the fork
print $_."\n";
$pmm->finish; # do the exit in the child process
}
$pmm->wait_all_children;
open(READ,"$log") or die $!;
my @check=<READ>;
print "there are ".scalar @arr ." items....";
print "but we only got ".scalar @check." items\n";
这是我要去的脚本的简化版本。 在这种情况下,每次我使用超过9个孩子,我会失去3-15个孩子,有时甚至更多。显而易见的答案是使用较少的孩子,但在我的“真实”脚本中,如果我使用较少的孩子,脚本将花费更多的时间来完成...我们没有的时间。为什么它会失去孩子?有没有办法“捕获”他们并重新运行它们如果他们不运行?
THX!
答案 0 :(得分:4)
您让所有的孩子都写入同一个日志文件,并且您没有采取任何措施来阻止他们覆盖彼此的输出。我无法在我的机器上重现问题,我无法肯定地说,但我猜所有N个孩子实际上都在运行,但是有些输出正在被破坏。
要让N个进程同时写入同一个文件而不丢失任何输出,您必须打开追加的文件而不是常规写入。在C中,您可以将标记O_WRONLY|O_APPEND
与open(2)
一起使用,或将模式"a"
与fopen(3)
一起使用。然后内核确保所有写入都到达文件的最后。 (但是根据手册页,这在NFS上是不可靠的。)你还必须注意一次写入文件多少,或者一个进程的输出可能会显示在另一个输出的中间。我不知道Perl中是否有可能出现这些问题,但听起来你还是找到了另一种解决方案。