【问题标题】:Sharing modules across python processes跨 python 进程共享模块
【发布时间】:2012-09-19 19:14:24
【问题描述】:

我们正在编写一个内存紧张的系统。有多个 python 进程将导入同一组类。如果进程加载了无数个类并且每个进程消耗了几百兆,那么 10 个进程和我正在运行 gigs。有没有办法跨 python 进程“共享”类导入?

总结:

import classA # Process 1 : loads classA in memory
import classA # Process 2 : reuses what was loaded previously by Process 1

PS:我想要实现的是你可以用 C/C++ 中的 .so 模块做的事情。

【问题讨论】:

  • 有什么原因不能像在 C 或 c++ 中那样在 python 中使用 dylib?您可以使用 ctypes 模块轻松加载它们,或者如果它们被编写为 python 扩展,则通过实际导入它们。

标签: python shared-libraries


【解决方案1】:

如果您的操作系统支持高效的写时复制 fork(很多都支持),那么至少可以节省一点内存。只需 import 在父级中创建所有内容,然后在 fork() 中创建所有子级。

请注意,如果您有许多小对象,则不会保存任何内容,因为需要写入对象的引用计数。但是,使用属性字典等大型静态结构可以节省大量成本。

【讨论】:

    【解决方案2】:

    我不相信这在 python 的设计中是可能的。如果这很重要,您可能希望使用线程而不是单独的进程。此外,如果您仅通过导入几个模块来运行 100 Megs,那么您可能在模块中做错了(似乎需要使用相当多的内存)。

    如果您绝对必须导入所有内容、不能减少内存使用并且不能使用线程,那么一种可能性是将大内存代码移动到用 C/C++ 编写的 python 扩展中。然后,这将允许您跨进程共享您的 python 扩展所在的共享库的公共段。它还可能会在一定程度上减少内存占用。

    附:在 python 中,您实际上是在导入模块,而不是类。与在 C/C++ 中包含头文件而不是类的方式类似。

    【讨论】:

    • 在 C 和 C++ 中,您没有导入任何内容。您正在自动复制和粘贴声明,并将编译后的代码链接在一起。
    • @delnan 是的,只是想指出导入的不是类,而是模块。因此,您不会共享类导入,而是共享模块导入。
    • 是的,我同意这一点。我只是容易吹毛求疵:)
    • "如果您绝对必须导入所有内容、不能减少内存使用并且不能使用线程,那么一种可能性是将大内存代码移动到用 C/C++ 编写的 python 扩展中。这个然后将允许您跨进程共享您的 python 扩展所在的共享库的公共部分”——我认为这不是真的。如果您跨 python 模块导入本机 .so ,您仍然会将它们全部放在每个模块的范围内,并且据我所知,导入行为会复制所有导入器模块中的每个类。对吗?
    • 我建议您可以将任何恒定数据(您希望跨进程共享的内容)作为恒定数据放在共享模块中。如果您需要公开说一百万个值的元组,而不是实际将元组公开给python,您将公开一个对象,该对象使用正确的运算符重载(或实现一个方法,我对细节很模糊)然后访问值的本机数组。这只是一个示例,您可能需要根据自己的需要调整基本理念。
    猜你喜欢
    • 2015-01-22
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-08
    • 2012-01-31
    • 1970-01-01
    相关资源
    最近更新 更多