微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在进程之间共享 NetworkX 图,没有额外的内存成本只读

如何解决在进程之间共享 NetworkX 图,没有额外的内存成本只读

我正在使用 python 的多处理模块。我有一个 networkx 图,我希望在许多子进程之间共享。这些子过程不会以任何方式修改图,而只会读取其属性(节点、边等)。现在每个子进程都有自己的图形副本,但我正在寻找一种在所有子进程之间共享图形的方法,这将导致整个程序的内存占用减少。由于计算非常占用 cpu,我希望以不会导致重大性能问题的方式完成此操作(如果可能,避免锁定等)。

注意:我希望它适用于各种操作系统,包括 Windows,这意味着 COW 没有帮助(如果我理解正确,由于引用计数,无论如何它可能都无济于事)

我找到了 https://docs.python.org/3/library/multiprocessing.html#proxy-objects 并且 https://docs.python.org/3/library/multiprocessing.shared_memory.html,但我不确定哪个(或者如果有)合适。解决这个问题的正确方法是什么?我使用的是 python 3.8,但如果有帮助,可以使用更高版本。

解决方法

在多处理期间在 python 中共享数据有几个选项,但您可能无法完全按照您的意愿行事。

在 C++ 中,您可以将简单的共享内存用于整数、浮点数、结构体等。Python 的共享内存管理器确实允许对简单对象进行这种类型的共享,但它不适用于类或任何比列表更复杂的东西基类型。对于共享的复杂python对象,你真的只有几个选择...

  1. 在您的 fork 进程中创建对象的副本(听起来您不想这样做)。

  2. 将对象放在一个集中的进程中(即..python 的管理器/代理对象)并通过管道和腌制数据与其交互。

  3. 将您的 networkX 图转换为简单整数列表并将其放入共享内存中。

什么对你有用取决于一些细节。选项#2 有一些开销,因为每次您需要访问对象时,都必须对数据进行腌制并通过管道传输到集中式进程,并对结果进行腌制/管道传输以返回。如果您一次只需要一小部分集中式数据,并且您的处理步骤相对较长(与 pickle/pipe 时间相比),这种方法很有效。

选项 #3 可能需要大量工作。您将从根本上将数据格式从 networkX 对象更改为整数列表,因此您的处理方式将发生很大变化。

不久前我将 PythonDataServe 放在一起,它允许您将数据从另一个进程提供给多个进程。这是与上面#2 非常相似的解决方案。如果您一次只需要一小部分数据,但您需要全部数据,则这种方法很有效,创建本地副本要容易得多。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。