0

我正在使用 subprocess.popen() 函数来运行一个外部工具,该工具将大量数据 (>GB) 读写到标准输出。但是,我发现内核在内存不足时正在杀死 python 进程:

Out of memory: Kill process 8221 (python) score 971 or sacrifice child
Killed process 8221 (python) total-vm:8532708kB, anon-rss:3703912kB, file-rss:48kB

因为我知道我正在处理大量数据,所以我设置了 popen 来将 stdout 和 stderr 写入文件,所以我不使用管道。我的代码看起来像这样:

errorFile = open(errorFilePath, "w")
outFile = open(outFilePath, "w")
#Use Popen to run the command
try:                
    procExecCommand = subprocess.Popen(commandToExecute, shell=False, stderr=errorFile, stdout=outFile)
    exitCode = procExecCommand.wait()

except Exception, e:
    #Write exception to error log       
    errorFile.write(str(e))     

errorFile.close()
outFile.close()        

我尝试将 shell 参数更改为 True 并设置 bufsize 参数 = -1 也没有运气。

我已经分析了运行此脚本和通过 bash 运行的内存,并且与 bash 相比,通过 Python 运行时,我发现内存使用量大幅增加。

我不确定 Python 到底在做什么来消耗比仅使用 bash 更多的内存,除非它与尝试将输出写入文件有关?bash 脚本只是将输出通过管道传输到一个文件。

我最初发现我的交换空间非常低,所以我增加了它,这最初有所帮助,但随着数据量的增长,我又开始耗尽内存。

那么我可以用 Python 做些什么来尝试更好地处理这些数据量,或者只是推荐更多内存和大量交换空间的情况。或者完全抛弃 Python。

系统详情:

  • Ubuntu 12.04
  • Python 2.7.3
  • 我正在运行的工具是来自 samtools 的 mpileup。
4

2 回答 2

1

问题可能是您使用的wait()方法(如在procExecCommand.wait()中)尝试将子进程运行到完成然后返回。尝试这个问题中使用的方法,例如stdout.read()在进程句柄上使用。通过这种方式,您可以定期清空管道、写入文件,并且不会堆积内存。

于 2012-07-17T14:44:47.677 回答
0

你的过程产生什么样的输出,也许线索就在其中。

警告:脚本不会终止,你必须杀死它。

此示例设置按我的预期工作。

import subprocess

fobj = open("/home/tst//output","w")

subprocess.Popen("/home/tst//whileone",stdout=fobj).wait()

而当一个

#!/bin/bash

let i=1
while [ 1 ]
do
 echo "We are in iteration $i"
 let i=$i+1
 usleep 10000
done
于 2012-07-17T14:48:13.620 回答