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

2024-05-18 07:14:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我在做一些生物信息学的工作。我有一个python脚本,它曾经调用一个程序来完成一个昂贵的过程(序列对齐..使用大量的计算能力和内存)。我用subprocess.Popen调用它。当我在一个测试用例上运行它时,它完成并完成得很好。但是,当我在完整的文件上运行它时,如果它必须为不同的输入集多次执行此操作,它就会死掉。子进程抛出:

OSError: [Errno 12] Cannot allocate memory

我发现有几个链接hereherehere指向类似的问题,但我不确定它们是否适用于我的案例。

默认情况下,序列对齐器将尝试请求51000M内存。它并不总是使用那么多,但它可能。在加载和处理完整的输入之后,就没有那么多了。但是,如果在运行时限制它请求的或将尝试使用的数量,使其低于可用的数量,则仍然会出现相同的错误。我也试过用shell=True和相同的东西运行。

这件事已经困扰我好几天了。谢谢你的帮助。

编辑:展开回溯:

File "..../python2.6/subprocess.py", line 1037, in _execute_child
    self.pid=os.fork()
OSError: [Errno 12] Cannot allocate memory

抛出错误。

Edit2:在64位ubuntu 10.4上运行python 2.6.4


Tags: 内存程序脚本数量here错误生物序列
3条回答

这与Python或subprocess模块无关。subprocess.Popen只是向您报告从操作系统接收到的错误。(顺便问一下,你用的是什么操作系统?)来自Linux上的man 2 fork

ENOMEM    fork()  failed  to  allocate  the  necessary  kernel  structures
          because memory is tight.

你要多次给subprocess.Popen打电话吗?如果是这样的话,那么我认为最好的方法是确保在下一次调用之前,您的进程的上一次调用被终止并被捕获。

我对6年后的操作感到非常抱歉,没有人提到这是Unix中非常常见的问题,实际上与python或生物信息学无关。对os.fork()的调用将临时加倍父进程的内存(父进程的内存必须对子进程可用),然后将其全部丢弃以执行exec()操作。虽然这个内存并不总是被实际复制的,但是系统必须有足够的内存来允许它被复制,因此,如果您是父进程,它使用了超过一半的系统内存,并且您的子进程甚至输出了“wc-l”,那么您将遇到一个内存错误。

解决方案是使用posix_spawn,或者在脚本开始时创建所有子进程,而内存消耗很低,然后在父进程完成其内存密集型任务之后再使用它们。

使用keyworks“os.fork”和“memory”的google搜索将显示几个关于这个主题的堆栈溢出帖子,可以进一步解释发生了什么:)

是否使用subprocess.PIPE?我遇到了问题,在使用它的时候读到了一些问题。临时文件通常可以解决这个问题。

相关问题 更多 >