了解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
我不明白为什么…请求的过程是微小的!
系统有足够的内存来存放更多的shell。

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

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

有关:

fork(),vfork(),exec()和clone()

fork()和内存分配行为

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

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

Solutions Collecting From Web of "了解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的可用参数根据您的具体需求,但这应该都是相对简单的。

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