我在数组中有数百个文件名。我想为数组中的每4个文件创建一个子进程,并让该子进程为这4个文件中的每一个做一些事情。 (因此,对于100个文件,我将创建25个进程。)
我在理解有叉子时处理线的顺序时遇到了一些麻烦。我以为我可以做这样的事情,但我陷入了困境:
foreach $file (@files) {
if ($f++ % 4 == 0) {
my $pid = fork();
if ($pid) {
push(@childs, $pid);
}
elsif ($pid == 0) {
... do stuff to $file ...
}
}
我认为这不对,我希望有人可以指出我正确的方向。感谢。
答案 0 :(得分:12)
除了使用fork
时遇到问题,您似乎也无法将@files
数组划分为较小的四个文件集。也许是这样的:
for (my $i = 0; $i < @files; $i += 4) {
# take a slice of 4 elements from @files
my @files4 = @files[$i .. $i + 3];
# do something with them in a child process
if (fork() == 0) {
... do something with @files4 ...
exit; # <--- this is very important
}
}
# wait for the child processes to finish
wait for 0 .. @files/4;
答案 1 :(得分:4)
use Parallel::ForkManager qw( );
my $pm = Parallel::ForkManager->new(int(@files/4));
for my $file (@files) {
my $pid = $pm->start and next;
... do something with $file ...
$pm->finish; # Terminates the child process
}
请注意,这仍会创建100个进程,它只是将其限制为25个并发。
如果您真的只需要25个进程,则可以使用以下命令:
use List::Util qw( min );
use Parallel::ForkManager qw( );
my $pm = Parallel::ForkManager->new(0+@files);
while (@files) {
my @batch = @files[0..min(4, $#files)];
my $pid = $pm->start and next;
for my $file (@batch) {
... do something with $file ...
}
$pm->finish; # Terminates the child process
}
答案 2 :(得分:1)
我会分组到一个数组,并让孩子处理该组
my $group = []
foreach my $file (@files) {
push @$group, $file;
if(scalar(@$group) % 4 == 0) {
my $pid = fork;
die "Unable to fork!" unless defined $pid;
push @childs, $pid if $pid;
children_work($group) unless $pid;
$group = [];
}
}
sub children_work {
my $group = shift;
// child, work with $group
exit(0);
}