如何在 Perl 中使用 fork() ?

发布于 2024-12-19 04:42:24 字数 384 浏览 0 评论 0原文

我的数组中有数百个文件名。我想为数组中的每 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 ...
  }
 }

我认为这是不对的,我希望有人能指出我正确的方向。谢谢。

I have hundreds of file names in an array. I want to create a child process for every 4 files in the array, and have that child do some stuff to each of those 4 files. (So with 100 files, I'll create 25 processes.)

I'm having some trouble understanding the order in which lines are processed when there's a fork. I was thinking I could do something like this, but I'm getting stuck:

foreach $file (@files) {
 if ($f++ % 4 == 0) {
  my $pid = fork();

  if ($pid) {
   push(@childs, $pid);
  }
  elsif ($pid == 0) {
    ... do stuff to $file ...
  }
 }

I don't think this is right, and I'm hoping someone can point me in the right direction. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

余厌 2024-12-26 04:42:24

除了使用 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;

In addition to your trouble using fork, you also seem to have trouble partitioning your @files array into smaller sets of four files. Maybe something like this:

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;
帅哥哥的热头脑 2024-12-26 04:42:24

使用 Parallel::ForkManager

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
}

Use Parallel::ForkManager

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
}

Note that this still creates 100 processes, it simply limits it to 25 concurrent.

If you truly want only 25 processes, you can use the following:

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
}
把人绕傻吧 2024-12-26 04:42:24

我将分组到一个数组,并让孩子处理该组

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);
}

i would group to an array, and let the child handle that group

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文