背景: 我对多进程Perl脚本没有多少经验。我有一个FooService的数据清理过程需要12个多小时才能完成,当我调查时,我发现几乎所有的时间都花在等待FooClient返回数据上。我正在研究一种多进程方式来完成这项任务,同事推荐了Parallel :: Fork :: BossWorkerAsync,而不是我以前做的简单fork()。我喜欢它,因为它减少了我的记忆用量。
问题: BossWorkerAsync看起来非常整洁,perldoc很棒,并且在无写测试模式下运行它的效果非常好,将我的执行时间推迟了一个小时。我唯一的问题是文档没有真正解释共享数据如何与" init_handler =>一起使用。 &安培; X"施工设置。我希望每个工作者都拥有自己的FooClient,以避免任何类型的同步问题。我选择了我认为正确的东西,但我有点偏执,并且还想确保我以最正确的方式处理这个问题。
代码:
# The number of children to spawn, modify after performance testing
Readonly my $CHILDREN => 40;
# Each child will set their own client
my $client;
my $bw = Parallel::Fork::BossWorkerAsync->new(
work_handler => \&process_keys,
init_handler => \&setup_client,
worker_count => $CHILDREN,
);
send_work($bw);
while ($bw->pending()) {
my $ref = $bw->get_result();
# Do stuff with the result
}
$bw->shut_down();
exit;
sub setup_client {
$client = FooClient->new();
}
我是否正在处理我不想正确分享的$ client?我保留了与fork()版本相同的协议,我在fork()之后设置$ client,但我只是担心这不是正确的方法。
答案 0 :(得分:2)
是的,您正在使用模块和init_handler。在每个子进程中,在进入阻塞选择循环之前,在fork之后调用该处理程序,等待作业。
我是该模块的作者。对不起,我花了很长时间才注意到这一点,并做出回应。很高兴看到代码被使用。
干杯, -Joe