如何使用 Parallel::ForkManager 进行管道传输?

发布于 2024-11-18 13:24:28 字数 405 浏览 2 评论 0原文

我想让子进程写入父进程的@array。我读过有关管道的内容,但我对如何实际实现它感到非常困惑:

use Parallel::ForkManager;
my @array;
my $pm=new Parallel::ForkManager(3); 

    for((1..5)){
    $pm->start and next; 
    print "child: ".$_."\n";
    push(@array,$_); # what do I do here to put it into the parent's @array????
    $pm->finish; 
    }
$pm->wait_all_children;


print "parent: ".$_."\n" for @array;

I want to have children processes write to the parent's @array. I've read about piping but I'm very confused on how to actually implement it:

use Parallel::ForkManager;
my @array;
my $pm=new Parallel::ForkManager(3); 

    for((1..5)){
    $pm->start and next; 
    print "child: ".$_."\n";
    push(@array,$_); # what do I do here to put it into the parent's @array????
    $pm->finish; 
    }
$pm->wait_all_children;


print "parent: ".$_."\n" for @array;

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

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

发布评论

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

评论(1

终陌 2024-11-25 13:24:28

如果您想使用管道,那么您需要在生成每个子项之前创建一对管道,从子项写入写入管道,然后使用 IO::Select 从父级中并行读取所有读取端。您还需要更改等待子级的方式,因为 ForkManager 的 wait_all_children 是阻塞的,这不是很有用。您可以使用 run_on_start 方法将每个进程注册到哈希中,并使用 run_on_finish 方法在每个进程终止后将其删除,然后在没有剩余进程时终止选择循环。

或者,如果子级可以将其结果实时传递回父级并不重要,您可以使用 ForkManager 的功能,通过 finish 调用在退出时将数据传递回父级,这看起来像就像:

#!perl
use strict;
use warnings;
use Parallel::ForkManager;

# No indirect object notation
my $pm = Parallel::ForkManager->new(3);
my @array;
$pm->run_on_finish(sub {
    my $return = $_[5]; # Count 'em.
    push @array, @$return;
});

for(1..5) {
  $pm->start and next;
  print "child: $_\n";
  $pm->finish(0, [$_]);
}

$pm->wait_all_children;

print "parent: $_\n" for @array;

这确实有效。

If you want to use pipes, then you need to create a pair of pipes before you spawn each child, write to the writing pipe from the child, and use IO::Select to read from all of the reading ends in parallel in the parent. You'll also need to change the way you wait for the children, since ForkManager's wait_all_children is blocking, which isn't very useful. You could use a run_on_start method to register each process in a hash and a run_on_finish method to delete each process after it dies, and then terminate the select loop when no processes are remaining.

Or, if it's not important that the children can pass their results back to the parent in realtime, you can use ForkManager's ability to pass data back to the parent on exit through the finish call, which would look something like:

#!perl
use strict;
use warnings;
use Parallel::ForkManager;

# No indirect object notation
my $pm = Parallel::ForkManager->new(3);
my @array;
$pm->run_on_finish(sub {
    my $return = $_[5]; # Count 'em.
    push @array, @$return;
});

for(1..5) {
  $pm->start and next;
  print "child: $_\n";
  $pm->finish(0, [$_]);
}

$pm->wait_all_children;

print "parent: $_\n" for @array;

which actually works.

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