我在Perl中使用常规的Parallel :: ForkManager模块。我执行大约10个子进程。 “ passes_thresholds”功能需要几毫秒或十亿分之一秒(选中)。如果我一个接一个地运行所有进程(没有Parallel :: ForkManager),整个过程将花费80-250毫秒。如果我将它们并行运行,则整个过程至少需要1秒钟。我发现前叉花了1秒钟来启动“完成”功能。当子进程完成工作时,我放置了一个计时器,应该进入“完成”功能。一秒钟对于我的发展来说太过分了。
sub parallel_execute {
my $this = shift;
foreach my $a (@a_array) {
my $pid = $this->{fork_manager}->start and next;
my $res = $a->passes_thresholds();
$a->{timer} = Benchmark::Timer->new();
$svc->{timer}->start;
$this->{fork_manager}->finish(0,{a => $a, plugin_result => $res});
}
}
$this->{fork_manager}->run_on_finish( sub {
my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_;
my $a = $data_structure_reference->{a};
if (exists $a->{timer}) {
$a->{timer}->stop;
debug "took: " . $a->{timer}->report;
}
});
您是否知道为什么至少需要1秒钟才能启动“完成”命令?
(我正在使用Unix服务器和perl 5.10)
答案 0 :(得分:2)
谢谢大家,我发现了问题。 ForManager模块具有“ waitpid_blocking_sleep”参数,默认情况下定义为1秒。有一个名为“ set_waitpid_blocking_sleep”的函数,我们可以定义此参数(睡眠时间)。我们可以设置零或秒的分数。我将此参数设置为零,并解决了我的问题。
答案 1 :(得分:1)
仅当P :: FM收割孩子时调用on_finish
回调,而P :: FM仅在以下三种情况下收割孩子:
$pm->start
时,已开始但未收获的子代数量等于最大值。$pm->reap_finished_children
时。$pm->wait_all_children
时。孩子离开与上述事件之一之间可能会有任意漫长的延迟。在您的程序中添加以下内容可以消除这种延迟:
$SIG{CHLD} = sub { $pm->reap_finished_children };
顺便说一句,如果您的孩子完成的工作仅花费“几毫秒或十亿分之一秒”,实际上您正在通过使用P :: FM放慢速度。传递给finish
的数据被序列化并写入磁盘,然后从磁盘读取并反序列化以进行on_finish
回调!