Parallel::ForkManager()模块是否支持对全局变量进行同步?

8
我对Perl中的Parallel::ForkManager模块非常陌生,但是它有很多优点,所以我认为它支持我需要的内容,只是我还没有想出来。
我需要在每个子进程中根据每个子进程计算出的键值将一些更新写入全局哈希映射表中。然而,当我在for循环外部声明一个哈希映射表并期望在循环后更新哈希映射表时,结果哈希映射表保持为空。这意味着虽然循环内的更新成功(通过打印值),但循环外部则不成功。
有人知道如何编写这样的代码以实现我想要的功能吗?
3个回答

6
这并不是一个特定于Perl的问题,而是理解Unix风格进程的问题。当你fork一个新进程时,默认情况下进程间没有共享内存。根据需要,有几种方法可以实现您想要的功能。
一种简单的方法是使用类似BerkeleyDB的东西将哈希与磁盘上的文件绑定。绑定的哈希可以在你fork之前初始化,然后每个子进程都可以访问它。 BerkeleyDB文件被设计为可以同时从多个进程安全地访问。
更复杂的方法是使用某种形式的进程间通信。有关实现此类通信的详细信息,请参见perlipc手册,其中详细介绍了Perl支持的几种IPC方法。
最后一种方法,如果您的Perl支持它,是使用线程并在它们之间共享变量。

4
每个fork调用都会生成一个全新的进程,因此在子进程中对哈希变量的更新在父进程中是不可见的(而在fork调用之后对父进程的更改在子进程中也是不可见的)。
您可以使用threads(还可以参考threads::shared)使一个线程中的更改可以被另一个线程写入。
另一种选择是使用进程间通信来在父进程和子进程之间传递消息。 Forks::Super模块(我是作者)可以减少这种情况的麻烦。
或者您的子进程可以将某些输出写入文件。当父进程收回它们时,它可以从那些文件中加载数据并相应地更新其全局哈希映射。

谢谢大家,现在我明白了! 我原本期望ForkManager()会处理这个问题。:-)在我的情况下,IPC可能过于复杂了。我喜欢使用ForkManager()简洁的方式,那么有没有一种简单的方法可以使用ForkManager()共享全局哈希映射表在进程之间? - galactica
3
从一个进程传递数据到另一个进程就是"IPC",这就是它的意思。不过,这并不一定很困难。 - hobbs
@Jin:是的,使用绑定哈希;请参见http://search.cpan.org/perldoc/BerkeleyDB。 - ysth

2
请阅读Parallel::ForkManager的man手册中“从子进程检索数据结构”部分。其中包含回调函数,可以发送子进程的数据,父进程可以检索并填充数据结构。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接