了解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