我有一个内存密集型的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位),所以我猜是子进程调用Fork。
Fork派生了我的现有进程,因此消耗的内存量增加了一倍,并且失败了??
“写入时复制”是怎么回事?
我可以在没有fork的情况下产生一个新的进程(或者至少不需要复制内存-重新开始)吗?
相关信息:
The difference between fork(), vfork(), exec() and clone()
发布于 2013-07-04 08:43:46
似乎不会出现真正的解决方案(即使用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的可用参数,但这应该是相对简单的。
您还会发现,在客户端启动时启动服务器,并在退出时管理要清理的套接字文件(或端口)是很简单的。
https://stackoverflow.com/questions/15443246
复制相似问题