7

プログラムがファイル ハンドルをリークしているようです。どうすれば場所を知ることができますか?

私のプログラムは、いくつかの異なる場所でファイル ハンドルを使用します。子プロセスからの出力、ctypesAPI の呼び出し (ImageMagick) によるファイルのオープン、およびそれらのコピーです。

でクラッシュしshutil.copyfileますが、これが漏れている場所ではないと確信しています。

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Python25\Lib\site-packages\magpy\magpy.py", line 874, in main
    magpy.run_all()
  File "C:\Python25\Lib\site-packages\magpy\magpy.py", line 656, in run_all
    [operation.operate() for operation in operations]
  File "C:\Python25\Lib\site-packages\magpy\magpy.py", line 417, in operate
    output_file = self.place_image(output_file)
  File "C:\Python25\Lib\site-packages\magpy\magpy.py", line 336, in place_image
    shutil.copyfile(str(input_file), str(self.full_filename))
  File "C:\Python25\Lib\shutil.py", line 47, in copyfile
    fdst = open(dst, 'wb')
IOError: [Errno 24] Too many open files: 'C:\\Documents and Settings\\stuart.axon\\Desktop\\calzone\\output\\wwtbam4\\Nokia_NCD\\nl\\icon_42x42_V000.png'
Press any key to continue . . .
4

6 に答える 6

4

subprocess.Popen() 呼び出し中にファイル記述子が不足するという同様の問題がありました。次のスクリプトを使用して、何が起こっているかをデバッグしました。

import os
import stat

_fd_types = (
    ('REG', stat.S_ISREG),
    ('FIFO', stat.S_ISFIFO),
    ('DIR', stat.S_ISDIR),
    ('CHR', stat.S_ISCHR),
    ('BLK', stat.S_ISBLK),
    ('LNK', stat.S_ISLNK),
    ('SOCK', stat.S_ISSOCK)
)

def fd_table_status():
    result = []
    for fd in range(100):
        try:
            s = os.fstat(fd)
        except:
            continue
        for fd_type, func in _fd_types:
            if func(s.st_mode):
                break
        else:
            fd_type = str(s.st_mode)
        result.append((fd, fd_type))
    return result

def fd_table_status_logify(fd_table_result):
    return ('Open file handles: ' +
            ', '.join(['{0}: {1}'.format(*i) for i in fd_table_result]))

def fd_table_status_str():
    return fd_table_status_logify(fd_table_status())

if __name__=='__main__':
    print fd_table_status_str()

このモジュールをインポートして呼び出しfd_table_status_str()、コードのさまざまなポイントでファイル記述子テーブルのステータスをログに記録できます。

また、subprocess.Popen インスタンスが破棄されていることを確認してください。Windows で Popen インスタンスの参照を維持すると、GC の実行が妨げられます。インスタンスが保持されている場合、関連するパイプは閉じられません。詳細はこちら

于 2014-05-20T14:22:46.747 に答える
3

ls -l /proc/$pid/fd/(もちろん、プロセスの PID に置き換えて)からの出力を見て、開いているファイルを確認します [または、win32 では、 Process Explorerを使用して開いているファイルを一覧表示します]。次に、コードのどこでそれらを開いているかを把握し、それclose()が呼び出されていることを確認します。(はい、ガベージ コレクターは最終的に物事を閉じますが、常に fds の不足を回避するのに十分な速さではありません)。

ガベージ コレクションを妨げている可能性のある循環参照をチェックすることもお勧めします。(サイクル コレクターは最終的にこれらを破棄しますが、ファイル記述子の枯渇を回避するのに十分な頻度で実行されない可能性があります。私は個人的にこれに悩まされています)。

于 2009-02-18T17:12:26.283 に答える
3

lsof -p <process_id>FreeBSD を含むいくつかの UNIX ライクなシステムでうまく動作します。

于 2010-12-19T23:01:21.787 に答える