了解Python分叉和内存分配错误

我有一个内存密集型Python应用程序(数百MB到几GB)。
我有几个主要应用程序需要运行的非常小的Linux可执行文件,例如

child = Popen("make html", cwd = r'../../docs', stdout = PIPE, shell = True)
child.wait()

当我使用subprocess.Popen运行这些外部实用程序(一次,在长主进程运行结束时),我有时会得到OSError: [Errno 12] Cannot allocate memory
我不明白为什么......请求的过程很小!
该系统有足够的内存来存放更多的炮弹。

我正在使用Linux(Ubuntu 12.10,64位),所以我想子进程调用Fork。
叉叉我现有的过程,从而加倍消耗的内存量,并失败??
“复制写入”发生了什么?

我可以在没有分叉的情况下产生新的进程吗(或者至少没有复制内存 - 从新开始)?

有关:

fork(),vfork(),exec()和clone()之间的区别

fork()和内存分配行为

Python subprocess.Popen错误与OSError:[Errno 12]不能分配内存一段时间后

使用subprocess.Popen的Python内存分配错误


看来不会有真正的解决方案即将出现(即使用vfork的子进程的替代实现)。 那么可爱的黑客怎么样? 在你的过程开始时,产生一个挂满小内存的奴隶,准备好衍生你的子过程,并在主流程的整个生命周期中保持开放的沟通。

下面是一个使用rfoo(http://code.google.com/p/rfoo/)和一个名为rfoosocket的命名的unix套接字的例子(显然,您可以使用其他连接类型rfoo支持或另一个RPC库):

服务器:

import rfoo
import subprocess

class MyHandler(rfoo.BaseHandler):
    def RPopen(self, cmd):
        c = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
        c.wait()
        return c.stdout.read()

rfoo.UnixServer(MyHandler).start('rfoosocket')

客户:

import rfoo

# Waste a bunch of memory before spawning the child. Swap out the RPC below
# for a straight popen to show it otherwise fails. Tweak to suit your
# available system memory.
mem = [x for x in range(100000000)]

c = rfoo.UnixConnection().connect('rfoosocket')

print rfoo.Proxy(c).RPopen('ls -l')

如果你需要实时来回处理与你产生的子进程交互的协处理,这个模型可能不起作用,但你也许可以将其破解。你可能想要清理可以传递给Popen的可用参数根据您的具体需求,但这应该都是相对简单的。

您还应该发现,在客户端启动时启动服务器并管理要在退出时清理的套接字文件(或端口)很简单。

链接地址: http://www.djcxy.com/p/12397.html

上一篇: Understanding Python fork and memory allocation errors

下一篇: Very lengthy stored procedure status