7

私の Python プログラムは、入力を準備し、外部の FORTRAN コードを実行し、Windows HPC 2008 環境で出力を処理します。コードが外部プログラムを 1042 ~ 1045 回実行しない限り、うまく機能します (通常、問題はより早く収束します)。これらの状況では、例外が発生します。

WindowsError: [エラー 206] ファイル名または拡張子が長すぎます

ただし、ファイル名へのパスは時間の経過とともに増加しません。ディレクトリを消去して再度実行するだけです。

コードは次のとおりです。

inpF = open(inName)
outF = open(localOutName,'w')
p = subprocess.Popen(pathToExe,shell=False,stdin=inpF,stdout=outF,cwd=runPath)
stdout, stderr = p.communicate()
outF.close()
inpF.close()

pathToExe は UNC の場所 (\\server\shared\program.exe など) を指す定数文字列です。stdin はローカル ドライブ上で読み取り専用モードで開いているファイルです。stdout はローカル ドライブ上で書き込みモードで開いているファイルです。 、cwd は C:\ ドライブ上のローカル パスです。このやや関連する投稿によると、制限は 32,768 であると想定されていますが、 subprocess への引数はどれも 80 文字を超えていないことを確認しました。

私は何を間違っていますか?どういうわけか、1000回以上実行したときにのみ問題になる何かが蓄積されています.

アップデート:

「開いているファイルが多すぎる」という仮説をテストするために、別の実行可能ファイルで非常に高速に実行される非常に小さな例を作成しました。ここでの主な違いは、stdin と stdout がここでは単なる空のファイルであるのに対し、前のケースでは両方とも大きなファイルであるということです。この場合、コードは 2000 回の実行で問題なく実行されますが、以前の実行は ~1042 で失敗します。つまり、ファイルがたくさんあるというだけではありません。開いている大きなファイルが多すぎる可能性がありますか?

import subprocess
for i in range(nRuns):
    if not (i % (nRuns/10.0)):
        print('{0:.2}% complete'.format(i/float(nRuns)*100))
    inpF=open('in.txt')
    outF=open('out.txt','w')
    p = subprocess.Popen('isotxsmerge.exe',shell=False,stdin=inpF,
                                 stdout=outF,cwd='.')
    stdout, stderr = p.communicate()
    outF.close()
    inpF.close()
4

2 に答える 2

4

うーん....実際には、エラー メッセージのテキストはアカニシンだと思います。確かなことはわかりませんが、ファイル ハンドルが不足していると思われます。さまざまな情報源から、標準的なファイル ハンドルの制限は約 2048 ファイルのようです...不思議なことに、これは 1042 サブプロセスの 2 倍近くです。Windows python インタープリターの内部構造はわかりませんが、ファイルを閉じているにもかかわらず、ハンドルのガベージ コレクションが十分に速く行われていないと推測されます。繰り返しますが...これは推測にすぎません...しかし、おそらくそれは、より決定的で生産的な何かにあなたを導くかもしれない別の考え方です.

当面の間、回避策として、プロセスを生成するガバナー プロセスを使用することで、古いスタンバイ アプローチを使用できます。中間サブプロセスには、死ぬまでの寿命が決まっています (たとえば、生成されるサブプロセスは 1000 以下です)。中間サブプロセスの有効期限が切れると、ガバナー プロセスは新しいサブプロセスを開始します。これはハックです...そしてそれは不器用なものです...しかし、うまくいきます。(IIRC、Apache Web サーバーは、サブプロセスが処理できる要求の数にある種の自己破壊制限を持っていました。)

とにかく...幸運と幸せなコーディングをお祈りします。

于 2012-05-23T19:05:14.150 に答える