flock

POPFile日本語版でKakasi(残念ながらスレッドセーフではないらしい)を使用するために発生する問題のバグフィクス、amatubu氏はsemaphoreを利用する実装を採用していたのだが何らかの?理由によりflockを使う実装に戻ってしまったとのこと。ファイルを利用する排他制御では考慮すべきことが色々ある。
たとえば重複起動チェック用ファイルの作成を試み既に同一ファイルが存在していて作成に失敗した場合は死んでしまうことにより、同一アプリの2重起動を防ぐ方式が昔から存在する。非常に手堅い方法なのだが実は致命的な欠点がある。起動をはじかれた際、アプリが動作しているかどうか確認して動作していない(つまり直前に動作していたプログラムが正常終了時の重複起動チェック用ファイルを削除する処理を行なえず死んでしまった)場合にそのファイルを削除するのはユーザーの責任だということである。確認ミスということも当然あるし、もっとあるのがこういうことを何回か繰り返すうちに改善を思いついて、プログラム起動直前に重複起動チェック用ファイルの削除ステップを起動スクリプト等に組み込んでしまうこと。私はこんなユーザーを責める気にはなれない。その次に考える対策というのはたとえば
重複起動チェック用ファイル作成直後に自身のプロセスIDをそのファイルに書き込む。起動時にチェック用ファイルが既に存在する場合、それに書かれたプロセスIDのプロセスが動作中かどうかチェックし、動作している場合は死んでしまい、動作していない場合は自分自身のプロセスIDで上書きして動作を継続する。一見改善のようであるが、重複起動チェック用ファイルを開きプロセスIDを読んでプロセスの実行をチェックしプロセスIDで上書きするまでの行為はatomicとは程遠く排他制御に大きな穴を開けてしまうことになる。このようなことを考える人の排他制御に関する感覚を、私はとても信用する気になれない。そんなこんなでファイルロック機能を利用する必要が出てくることになるのだろう。
今までの説明で何となく感じられると思うが、ファイルロック機能を利用する際にはファイルロックのみに専念した方が安全であるということ。たとえばロックファイルを作成してロックし、ロック解除時には丁寧にファイル削除まで行う等、ファイルのライフサイクルを全部面倒見るのはかえって危険を招いてしまいます。私が採用していたのは、ロックファイルはプログラムの外であらかじめ割り当ててしまい、プログラム内では(開いて)ロックする、ロック解除する(+閉じる)という動作だけを行うというやり方でした。特にファイルの削除は厳禁です。外からは見えないゾンビファイルを作ってしまい同一ファイル名のファイルの作成を許す原因となりがちです。もっともWindowsの場合はファイル削除がUNIXほど簡単には出来ないので意外と安全かもしれませんが、platform-specificな事を当てにするのはよした方がよいでしょう。
ただflockの利用は汎用性にかなり疑問がある。サポートされないプラットフォームもあるみたいだし、サポートされていてもスレッド単位のロックがかかるかのかどうか?プロセス単位のロックしかサポートしていなくても不思議ではないと思う。