我被建议用Parallel::ForkManager
妖魔化。如您所见,我使用run
进行妖魔化。
sub run {
my ($self) = @_;
my $pfm = Parallel::ForkManager->new($self);
while(1) {
$pfm->run_on_wait( sub {
#some code here
},sleep(0.0001));
my $pid = $pfm->start;
if ($pid != 0) {
# Parent process
push @childs, $pid;
sleep 1;
next;
}
# Child process; do some work
$self = &doWork();
# Worker finished, clean up the $pfm instance
$pfm->finish();
}
}
所有子PID都存储在数组@childs
中,如果其中一个死了,循环允许恢复所需数量的子节点,但是旧的(死)PID在数组中,如何删除它们?并且新数组是否会在位于run_on_wait
的代码中可见。
答案 0 :(得分:1)
我认为你在滥用Parallel::ForkManager
。
它的作用/用途是允许您自动限制多个进程。
在调用构造函数(new
)时指定限制。
E.g:
my $pfm = Parallel::ForkManager -> new ( $n_concurrent );
通常$self
用于表示面向对象的调用。
run_on_wait
方法与你正在做的事情非常相关,所以如果你展示它会有所帮助。但我认为你误解了它的用途,因为你在while
循环的每次迭代都重新定义它。
run_on_wait $code, [$period]
You can define a subroutine which is called when the child process needs to wait for the startup. If $period is not defined, then one call is done per child. If $period is defined, then $code is called periodically and the module waits for $period seconds between the two calls. Note, $period can be fractional number also. The exact "$period seconds" is not guaranteed, signals can shorten and the process scheduler can make it longer (on busy systems).
但它并不打算在其中嵌入sleep
。它应该包括一个等待延迟,并且它将运行'wait'代码被调用。
但是重新定义while循环的每次迭代也没有意义。目前还不清楚你首先使用@childs
的内容 - 为什么你需要维护一个pid列表 - Parallel::ForkManager
正在跟踪数字并处理加入/等待你。
如果您因某些其他原因需要跟踪您的孩子 - 那么您可能会发现使用“开始”和“完成”机制更有用。
start [ $process_identifier ]
This method does the fork. It returns the pid of the child process for the parent, and 0 for the child process. If the $processes parameter for the constructor is 0 then, assuming you're in the child process, $pm->start simply returns 0.
An optional $process_identifier can be provided to this method... It is used by the "run_on_finish" callback (see CALLBACKS) for identifying the finished process.