5

次の Python 3 コードを実行すると、(少なくとも私にとっては) 奇妙な動作が見られますstrace

import os
import sys

if len(sys.argv) != 2:
    print('Usage: ecpy <filename>')
sys.exit(1)
try:
    print('my PID: %d' % os.getpid())
    with open(sys.argv[1], 'w') as fp:
        try:
            fp.write('Hello Stack Overflow!')
        except IOError as e:
            print('### before close')
            print(str(e))
            sys.stdout.flush()
except IOError as e:
    print('### after close')
    print(str(e))
    sys.stdout.flush()

print('### after exception block')
sys.stdout.flush()

I/O はバッファリングされるため、このコードを で実行すると、ブロックの最後で が閉じる/dev/fullまで失敗しません。それは驚くべきことではありません。Python 2.7.3rc2 (私のシステム上) では、コードは、に対応するファイル記述子を実際に閉じた後に例外ハンドラーを実行します。fpwithfp

write(3, "Hello Stack Overflow!", 21)   = -1 ENOSPC (No space left on device)
close(3)                                = 0
munmap(0x7f9de3f78000, 4096)            = 0
write(1, "### after close\n", 16)       = 16
write(1, "[Errno 28] No space left on devi"..., 35) = 35
write(1, "### after exception block\n", 26) = 26

ただし、Python 3.2.3 (私のシステム) では、例外ブロックの実行後もファイル記述子が開いたままです。

write(3, "Hello Stack Overflow!", 21)   = -1 ENOSPC (No space left on device)
write(1, "### after close\n", 16)       = 16
write(1, "[Errno 28] No space left on devi"..., 35) = 35
write(1, "### after exception block\n", 26) = 26
...
write(3, "Hello Stack Overflow!", 21)   = -1 ENOSPC (No space left on device)
write(3, "Hello Stack Overflow!", 21)   = -1 ENOSPC (No space left on device)
close(3)                                = 0

インタープリターはファイルへの書き込みをさらに数回試みますが、黙って失敗します。Python が実際に呼び出すのはclose()いつですか? それを呼び出すのは何ですか?この動作は、ファイル記述子をリークしているようです。

4

1 に答える 1

2

私は自由に問題を bugs.python.org に提出しました。

http://bugs.python.org/issue16597

編集: バグのようですが、うまくいきました!

于 2012-12-02T23:31:39.650 に答える