【问题标题】:How can I share simple scalar (counter variable) between forks in perl?如何在 perl 中的 fork 之间共享简单的标量(计数器变量)?
【发布时间】:2011-08-05 05:17:02
【问题描述】:

我一直在编写一个多次分叉的程序,每个分叉也可能分叉成更小的部分。

每个最低级别的孩子最终都在运行一个复杂的计算并将结果输出到一个唯一命名的文件中。

ID 必须是唯一的,这样当所有子代都完成后,父代可以收割子代,然后收集数据。

作为一个更具体的示例,每个孩子将生成一个文件$unique_id.storable,其中包含各自孩子已处理的数据。

当父级发现所有子级都已完成时,它使用 storable 将文件读回到哈希中,并使用希望唯一的 $unique_id 作为键。

当两个孩子几乎同时产生时,问题就出现了。现在,每个孩子最终都会运行自己的独立计数器,因此多个孩子都可以创建一个名称相似的$unique_id,即使这些文件中的数据确实是唯一的。

如何在分叉之间共享一个计数器变量,一个纯标量?

我意识到进程间通信的问题在互联网上相当普遍,但我注意到许多解决方案解决了进程之间共享任意数量数据的一般问题。我只需要共享一个标量,所以我想知道我的问题是否可以以更简单的方式处理。理想情况下,实际上非常理想,我更喜欢不涉及“非标准”模块的解决方案。我看到有时建议使用IPC::Shareable,但我想知道这对我的问题来说是否有点矫枉过正,无论如何,这是那些“非标准”模块之一。

如果我将我的$unique_id 设为 PID 是否明智?父程序是否有可能在一个使用率很高的机器上运行一个星期,可能会重用 PID 而不能保证唯一性?

如果有人可以提供任何建议,我将不胜感激。

【问题讨论】:

  • 是的,所以发布的解决方案并没有直接解决我使用某种形式的 IPC 的愿望,但它们确实解决了我的问题,即我的 perl 程序的分支之间有一个唯一的计数器变量。

标签: perl ipc fork parent-child shared-memory


【解决方案1】:

你为什么不把 id 传下来呢?根进程产生

1
2
...

这些,依次产生

1.1
1.2
...

2.1
2.2
...

...

等等。

【讨论】:

  • 身份证?你指的是PID吗?
【解决方案2】:

我可能会使用稍微不同的方法:您可以通过文件名处理所有内容...

就唯一 PID 而言,是的,您的 PID 可能会在一周左右后回收,因此无法保证它们是唯一的。但是,您可以将日期/时间附加到文件名以确保唯一性。

要让父级跟踪它需要收集的所有结果文件,您可以简单地在父级中生成一个唯一的作业 ID,然后在子级树中保持这个常量。您可以将此作业 ID 用作结果文件的前缀,因此最终父级只需读取所有具有适当前缀的文件。

文件名最终会看起来有点麻烦,但它们只是临时文件,对吧?

生成的文件名如下所示:

<job_id>_<pid>_<created_time>.storable

然后父级只查找所有文件&lt;job_id&gt;_*.storable

【讨论】:

    【解决方案3】:

    您可以使用 pid 并确信它是唯一的,方法是让父级仅在父级处理了子级的输出后获取子级。

    # Wait for a child to terminate, but don't reap it yet.
    my $pid = waitpid(-1, WNOWAIT);
    
    # Collect data from the file for child $pid
    ...
    
    # Reap the child.
    waitpid($pid, 0);  
    

    但在我看来,如果你能做到这一点,你可以使用管道而不是临时文件进行通信。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-24
      • 2012-05-19
      • 1970-01-01
      • 2011-02-09
      • 2019-10-16
      • 1970-01-01
      • 2013-06-10
      • 2020-04-29
      相关资源
      最近更新 更多