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

私は大量のデータを処理していることを知っているので、パイプを使用していないので、stdout と stderr をファイルに書き込むように popen をセットアップしました。私のコードは次のようになります。

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 を介してメモリをプロファイリングしましたが、Python を介して実行すると、bash と比較してメモリ使用量に大きなスパイクが見られます。

出力をファイルに書き込もうとすることに何か関係がない限り、Pythonがbashを使用するよりもはるかに多くのメモリを消費するために正確に何をしているのかわかりませんか? bash スクリプトは、出力をファイルにパイプするだけです。

最初はスワップ領域が非常に少ないことがわかったので、それを増やして最初は助けましたが、データの量が増えると、再びメモリが不足し始めました。

これらのデータ ボリュームをより適切に処理するために Python でできることはありますか。それとも、十分なスワップ スペースを備えたより多くのメモリを推奨する場合にすぎませんか。それかPythonを完全に放棄します。

システムの詳細:

  • Ubuntu 12.04
  • パイソン 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 に答える