エントリー

ファイルロック解除処理

またもPHPでの排他処理について。ファイルに書き込みを行う場合は

$fp = fopen('data.txt', 'r+') or exit('error!');
flock($fp, LOCK_EX);

~ここで書き込みを行う~

flock($fp, LOCK_UN);
fclose($fp);

で問題ないと思ったけど、まだ駄目っぽい。ロックの解除に問題があり、ファイルの破損は完全に回避できないらしい。調べてみると色々出てきた。

@ITのPHPの記事が突っ込みどころ満載 - 暴言満載

fcloseの前にflock(ファイルポインタ, LOCK_UN) する人は実に多いのですが、これははっきりと間違いだと断言します。flockをfcloseの前に解除するということは、fcloseの前に他のプロセスが割り込む可能性が出るということです。ファイルへの書き込みは、fwriteとかfputsとかしてからfflushまたはfclose実行までのどこかで行われる、というのがファイル周りのI/Oの基本です。なので、fcloseもロックの範囲内に入れなければなりません。fcloseでflockが解除されるのはそういう理由があるのです。

PHP/ファイルロック/設計 - TestWiki - PukiWiki Plus!

プロセスレベルの書き込みバッファによって、書き込みデータがOSに渡されずに残っている可能性がある。

fflush($fp);
flock($fp, LOCK_UN);
fclose($fp);

で明示的にフラッシュするか、flock($fp,LOCK_UN)しない

fclose($fp); // LOCK_UN してはならない

をすることで、バッファがフラッシュされた後、ロックが解除される。

PHP: flock - Manual

ロックの解放には fclose() でを使用します (これは、スクリプトが終了した場合にも自動的にコールされます)。

公式サイトの解説は「ロックの解放には fclose() でを使用します」と書いている割に、サンプルコードでは flock($fp, LOCK_UN); で解除しています。こんな風に書かれていたら、どっちでも大丈夫なのかと思ってしまうよ…。
公式サイトのサンプルコードは、あまり信用しないほうがいいのかなぁ…。公式サイトなのに。

ついでに書くと「でを使用します」って誤字ですよね…?

ともかく、ロックの解除は fclose() にまかせて

$fp = fopen('data.txt', 'r+') or exit('error!');
flock($fp, LOCK_EX);

~ここで書き込みを行う~

fclose($fp);

が正しいっぽい。

ページ移動

ユーティリティ

カテゴリー

検索

エントリー検索フォーム
キーワード

過去ログ

過去ログ表示フォーム
キーワード

Feed