gpt4 book ai didi

perl - 循环内 fork 防止迭代器使用 Parallel::Prefork 递增

转载 作者:行者123 更新时间:2023-12-04 04:48:36 27 4
gpt4 key购买 nike

我有一些代码,我希望输出为 1 和 6,但它会无限输出 1。

use v5.10;
use Parallel::Prefork;
use List::MoreUtils qw( natatime );
use POSIX qw( ceil );

my $forks = 2;

my @numbers = (1..10);
my $chunk_size = ceil((scalar @numbers) / $forks);
my $game_iterator = natatime $chunk_size, @numbers;
my $fm = Parallel::Prefork->new({ max_workers => $forks });

while ($fm->signal_received ne 'TERM') {
while( my @numbers_chunk = $game_iterator->() ) {
$fm->start(sub {
say $numbers_chunk[0];
});
}
}

$fm->wait_all_children;

# bash-4.2$ perl test.pl
# 1
# 1
# 1
# 1
# 1
# etc

上面的脚本将一个包含 10 个数字的数组拆分为 $fork 个数组 (2),并且应该将每个数组传递给它们自己的 fork 进行处理。

如果替换 $fm->start(sub {say $numbers_chunk[0];});只需 say $numbers_chunk[0];显示正确的结果。 Parallel::ForkManager 还输出正确的结果(按照概要),所以我不知道我做错了什么,或者这是否是模块中的错误。

输出预期结果的 ForkManager 脚本:
use v5.10;
use Parallel::ForkManager;
use List::MoreUtils qw( natatime );
use POSIX qw( ceil );

my $forks = 2;

my @numbers = (1..10);
my $chunk_size = ceil((scalar @numbers) / $forks);
my $game_iterator = natatime $chunk_size, @numbers;
my $fm = Parallel::ForkManager->new($forks );

while( my @numbers_chunk = $game_iterator->() ) {
$fm->start and next;
say $numbers_chunk[0];
$fm->finish;
}

$fm->wait_all_children;


# bash-4.2$ perl test.pl
# 1
# 6

最佳答案

与文档相反,Parallel::Prefork 与 Parallel::ForkManager 非常不同。它的设计目的是供网络服务器之类的东西使用,它会加载一次配置,然后生成相同的子节点,直到它被信号关闭。

因此,start根据需要不断创建子进程,并且在捕获到终止整个进程的信号之前不会返回。

也就是说,可以使用 before_fork 使 P::Prefork 像胖版本的 P::ForkManager 一样工作。 .

use strict;
use warnings;
use v5.10;

use List::MoreUtils qw( natatime );
use Parallel::Prefork qw( );
use POSIX qw( ceil );

my $forks = 2;

my @numbers = (1..10);
my $chunk_size = ceil(@numbers / $forks);
my $game_iterator = natatime($chunk_size, @numbers);

my @numbers_chunk;

my $fm = Parallel::Prefork->new({
max_workers => $forks,
trap_signals => { TERM => 'TERM' },
before_fork => sub {
@numbers_chunk = $game_iterator->()
or kill(TERM => $$);
},
});

$fm->start(sub {
say $numbers_chunk[0];
});

$fm->wait_all_children();

但是为什么不直接使用 Parallel::ForkManager 而不是强制 Parallel::Prefork 来模拟它呢?

关于perl - 循环内 fork 防止迭代器使用 Parallel::Prefork 递增,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17793468/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com