【问题标题】:How to remove dead children from the array in perl Parallel::ForkManager?如何从 perl Parallel::ForkManager 中的数组中删除死子?
【发布时间】:2014-11-19 16:55:06
【问题描述】:

有人建议我使用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,但数组中存在较旧(死)的 PI​​D,如何删除它们?并且新数组是否会在位于run_on_wait 的代码中可见。

【问题讨论】:

  • 你为什么将$self 传递给Parallel::ForkManager?你想用@childs 完成什么?
  • 一开始就构建数组没有多大意义。你想完成什么?
  • @childs 中的 pids 用于 dbi 中的 updatedoWork() 检查数据库中的这个 pid。 $self 仅用于设置最大孩子数,没关系,我可以使用静态变量。
  • 很奇怪的事情——$self 通常用于表示面向对象的代码。
  • 我不好,这个方法基于example,who based for oop

标签: arrays perl fork daemon


【解决方案1】:

我认为你在滥用Parallel::ForkManager

它的作用/用途是允许您自动限制多个进程。

您在调用构造函数时指定限制 (new)。

例如:

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。它应该包括一个等待延迟,它会运行'等待'代码被调用。

但是,在 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.

【讨论】:

  • run_on_wait 中的代码必须连续执行(无限循环)。它实现了一个数据库操作(有两个基础)。此代码中使用的子进程的 PID。 doWork() 来自另一个必须像守护进程一样工作的脚本的方法(检查位于数据库和其他操作中的 PID)。
  • 你仍然不需要在 while 循环的每次迭代中重新定义 sub。
  • 把它变成一个哈希。插入 pid 作为哈希键,然后使用delete
  • 问题不在于如何从数组中移除,而在于如何确定哪些PID是死的。据我了解,run_on_wait 方法在启动第一个孩子时运行。当需要运行的孩子数量时如何运行它?
  • run_on_finish 在进程完成时运行。您可以在开始流程时嵌入身份。
猜你喜欢
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 2011-01-26
  • 2017-06-12
  • 1970-01-01
  • 2018-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多