0

サブプロセスを介してアプリケーションを何度も (数千回) 実行する python cgi スクリプトがあります。私は同じエラーが発生し続けます...

Traceback (most recent call last):
  File "/home/linuser/Webpages/cgi/SnpEdit.py", line 413, in <module>
    webpage()
  File "/home/linuser/Webpages/cgi/SnpEdit.py", line 406, in main
    displayOmpResult(form['odfFile'].value)
  File "/home/linuser/Webpages/cgi/SnpEdit.py", line 342, in displayContainerDiv
    makeSection(position,sAoiInput)
  File "/home/linuser/Webpages/cgi/SnpEdit.py", line 360, in displayData
    displayTable(i,j,lAmpAndVars,dOligoSet[key],position)
  File "/home/linuser/Webpages/cgi/SnpEdit.py", line 247, in displayTable
    p = subprocess.Popen(['/usr/bin/pDat',sInputFileLoc,sOutputFileLoc],stdout=fh, stderr=fh)
  File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
    errread, errwrite)
  File "/usr/lib/python2.6/subprocess.py", line 1039, in _execute_child
    errpipe_read, errpipe_write = os.pipe()
OSError: [Errno 24] Too many open files

それを引き起こす機能は以下です。

def displayTable(sData):

    # convert the data to the proper format
    sFormattedData = convertToFormat(sData)

    # write the formatted data to file
    sInputFile = tempfile.mkstemp(prefix='In_')[1]
    fOpen = open(sInputFile,'w')
    fOpen.write(sFormattedData)
    fOpen.close()

    sOutputFileLoc = sInputFile.replace('In_','Out_')

    # run app, requires two files; an input and an output
    # temp file to holds stdout stderr of subprocess
    fh = tempfile.TemporaryFile(mode='w',dir=tempfile.gettempdir())
    p = subprocess.Popen(['/usr/bin/pDat',sInputFileLoc,sOutputFileLoc],stdout=fh, stderr=fh)
    p.communicate()
    fh.close()

    # open output file and print parsed data into a list of dictionaries
    sOutput = open(sOutputFileLoc).read()
    lOutputData = parseOutput(sOutput)

    displayTableHeader(lOutputData)
    displaySimpleTable(lOutputData)

私が知る限り、ファイルを適切に閉じています。走ると…

import resource
print resource.getrlimit(resource.RLIMIT_NOFILE)

私は...

(1024, 1024)

この値を増やす必要がありますか? サブプロセスがいくつかのファイル記述子を開くことを読みました。「close_fds = True」を追加してみて、ファイルを作成するときに with ステートメントを使用してみましたが、結果は同じでした。問題は、私がサブプロセスしているアプリケーション pDat にあるのではないかと思いますが、このプログラムは他の人によって作成されたものです。2 つの入力が必要です。入力ファイルと、出力ファイルを書き込む場所の場所。作成した出力ファイルを閉じていない可能性があります。これを除けば、何が間違っているのかわかりません。助言がありますか?ありがとう。

編集:私はPython 2.6.5とApache 2.2.14を実行しているubuntu 10.04を使用しています

4

2 に答える 2

1

これの代わりに...

sInputFile = tempfile.mkstemp(prefix='In_')[1]
fOpen = open(sInputFile,'w')
fOpen.write(sFormattedData)
fOpen.close()

こうすれば良かった…

iFileHandle,sInputFile = tempfile.mkstemp(prefix='In_')
fOpen = open(sInputFile,'w')
fOpen.write(sFormattedData)
fOpen.close()
os.close(iFileHandle)

mkstemp 関数は、ファイルへの OS レベルのハンドルを作成しますが、それらを閉じていませんでした。ソリューションについては、こちらで詳しく説明しています... http://www.logilab.org/blogentry/17873

于 2012-09-11T19:34:14.867 に答える
0

通話に追加close_fds=Trueしたい(念のため)。popen

次に、ここに:

# open output file and print parsed data into a list of dictionaries
    sOutput = open(sOutputFileLoc).read()
    lOutputData = parseOutput(sOutput)

...私の記憶違いかもしれませんが、with構文を使用しない限り、出力ファイル記述子が閉じられているとは思いません。

更新: 主な問題は、開いているファイルを知る必要があることです。Windows では、これには Process Explorer のようなものが必要です。Linux ではもう少し単純です。コマンド ラインから CGI を呼び出すか、実行中の CGI のインスタンスが1 つしかないことを確認し、コマンドでその pid をフェッチするだけpsです。

pid を取得したら、ディレクトリls -laの内容に対して a を実行します。/proc/<PID>/fd開いているすべてのファイル記述子がそこにあり、それらが指すファイルの名前が付いています。ファイルが377回開かれていることを知っていると、そのファイルが開かれている(閉じられていない)正確な場所を見つけるのに大いに役立ちます。

于 2012-08-30T13:51:57.267 に答える