私はstrace
を通してそれを実行すると、次のPython 3のコードは、(少なくとも、私には)いくつかの奇妙な挙動を示す:.close()が失敗したときに、Python 3でファイル記述子はどうなりますか?
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
でこのコードを実行した場合、それはdoesnのブロックwith
の最後でfp
が終了するまで失敗します。それは驚きではありません。 (私のシステム上の)Pythonの2.7.3rc2では、コードが実際にfp
に対応するファイルディスクリプタを閉じた後に例外ハンドラを実行します:
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()
を呼び出しますか?それを呼び出すのは何ですか?この動作は、ファイル記述子をリークするようです。
提出いただきありがとうございます。 –