如何在perl中的forks之间共享简单的标量(计数器变量)?

时间:2011-04-14 03:35:27

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

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

每个最低级别的孩子最终都在进行复杂的计算并输出结果,我希望这是一个唯一命名的文件。

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

作为一个帮助使其更具体的示例,每个孩子都会生成一个文件$unique_id.storable,其中包含相应孩子已处理的数据。

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

当两个孩子几乎同时产生时,问题出现了。眼下,这些孩子的最终运行自己独立的计数器,以便在多个孩子都可能创建一个类似命名的$unique_id,即使这些文件中的数据确实是独一无二的。

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

我知道进程间通信的问题是对interwebs相当常见的,但我注意到许多解决方案解决了共享的进程之间的数据的任意数量的一个普遍的问题。我只需要共享一个标量,所以我想知道我的问题是否能以更简单的方式处理。理想情况下,理想情况下,我更喜欢一种不涉及非标准的解决方案。模块。我发现IPC::Shareable有时候会被推荐,但我想知道这对我的问题是否有点过分,而这是其中一个非标准的"无论如何,模块。

如果我将$unique_id设为PID,那会是明智的吗?是否有可能运行在的说,一周一个疗程,使用频繁的机器上的父程序,可能会重用PID和不保证唯一性?

我很欣赏人们可以借出的任何建议。

3 个答案:

答案 0 :(得分:4)

你为什么不把这个id传下去?根进程产生

1
2
...

这些又反过来产生

1.1
1.2
...

2.1
2.2
...

...

等等。

答案 1 :(得分:2)

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

就唯一的PID而言,是的,有可能在一周左右之后,您的PID将会循环使用,以确保它们不会是唯一的。但是,您可以将日期/时间附加到文件名以确保唯一性。

要允许父级跟踪它需要收集的所有结果文件,您只需在父级中生成一个唯一的作业ID,然后通过子树树保持此常量。您可以使用此作业ID作为结果文件的前缀,因此最终父级只会读取具有相应前缀的所有文件。

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

生成的文件名如下所示:

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

然后父母只查找所有文件<job_id>_*.storable

答案 2 :(得分:2)

您可以使用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);  

但在我看来,如果你能做到这一点,你可以用管道代替临时文件。