ファイルを unlock して問題になるくらいなら、OS 任せにするほうがよい
476 名前: デフォルトの名無しさん Mail: sage 投稿日: 2008/03/05(水) 23:48:04 ファイルの排他制御のテストプログラムを書いています。 ただ単に1つのカウントファイルを100万回インクリメントするプログラム #!/usr/bin/env python for i in range(1000000) : f = open("count-file", "r+") fcntl.flock(f.fileno(), fcntl.LOCK_EX) cnt = f.readline() cnt = int(cnt) + 1 f.seek(0) f.write("%d\n" % cnt) fcntl.flock(f.fileno(), fcntl.LOCK_UN) f.close() を同時に2つ実行するとcount-fileの値が 2000000 になるはずが、 1984329 という風に途中で欠けてしまいます。但し1つ実行する分には正常に動作します。 排他制御がうまくいってないようなのですがどこがいけないのでしょうか。 flockの部分をlockfにしても変化はありません。 OS Gentoo、python 2.5.1 477 名前: デフォルトの名無しさん Mail: sage 投稿日: 2008/03/05(水) 23:52:06 LOCK_UN の前に flush? 478 名前: デフォルトの名無しさん Mail: sage 投稿日: 2008/03/05(水) 23:56:25 >>477 まさにおっしゃる通りでしたorz 的確なアドバイス助かりました m(_ _)m
f.flush() を追加するのでもいいけど、LOCK_UN を実行しないというのでもいいよね。
MS-DOS ならいざ知らず、最近の OS なら f.close() するときに「バッファの flush」と「ファイルの unlock」の両方をしてくれる。つまり OS が面倒見てくれるから、必要な後処理は OS に任せてしまいましょう、ということ。プログラマーが勝手に unlock して問題になるくらいなら、OS 任せにしたほうがいい。resource を管理するために OS があるんだから。
排他的ロックをしてるのに、1 プロセスより 2 プロセスのほうが速い?
ところで、<<476 のコードを改造して実験してみたとき、よくわからん現象に見舞われた。1 プロセスだと 1 分近くかかるのに、2 プロセスだと 15 秒で終わってしまうのだ。
コード (hoge.py):
#!/usr/bin/env python N = 100000 filename = 'count-file' from fcntl import flock, LOCK_EX, LOCK_UN for i in xrange(N): f = open(filename, 'r+') flock(f.fileno(), LOCK_EX) s = f.readline() cnt = s and int(s) + 1 or 1 f.seek(0) f.write(str(cnt)) #flock(f.fileno(), LOCK_UN) f.close()
1 プロセスで実験:
$ echo 0 > count-file $ time python hoge.py real 0m52.042s user 0m5.929s sys 0m7.689s $ cat count-file 100000
2 プロセスで実験:
$ echo 0 > count-file $ time python hoge.py & [1] 15324 $ time python hoge.py real 0m15.742s user 0m3.983s sys 0m5.387s [1]+ Done time python hoge2.py real 0m15.250s user 0m7.940s sys 0m10.725s $ cat count-file 200000
1 プロセスだと 52 秒かかるのに、2 プロセスだと各々 15 秒で済んでいる。このスクリプトは処理を分散するタイプではなく、排他的にロックを獲得しないといけないから、プロセスが増える方が実行時間は増えるはずなのに、結果はまったく逆になった。
さっぱり意味がわからん。誰か原理を教えてください。
環境は MacOS X 10.4 Tiger, Intel CoreDuo 1.83GHz, Python 2.5.2 です。