PHP の flock 関数を数年ぶりに使用したのですが、すごい勘違いをしていました。DB を使用するようになってからいうものめっきりファイルロックなど使わなくなっていたので。。。(言い訳です^^)

PHP: flock – Manual

返り値
成功した場合に TRUE を、失敗した場合に FALSE を返します。

と書かれていたので、てっきりロックできなかった場合に FALSE が返るのかと思っていました。

$fp = fopen(dirname(__FILE__)."/lock", "w+");
if (!flock($fp, LOCK_EX)) {
    triger_error('排他処理中のため実行できません', E_USER_ERROR);
}

として、sleep(60) などで実行を1分間止めて同じプログラムを実行し、ロックできなくてエラーになると想定してテストをしてみたところ、ロックできるまで待ってからロックして実行していました。

ロックされている場合にロックが解除されるのを待たずにすぐに次の処理をしたい場合はマニュアルの operation の説明にある LOCK_NB を使えばよいようです。

ロック中に flock() でブロックを行いたくない場合は、 LOCK_NB をセットします (Windows ではサポートされていません)。

$fp = fopen(dirname(__FILE__)."/lock", "w+");
if (!flock($fp, LOCK_EX|LOCK_NB)) {
    trigger_error('排他処理中のため実行できません', E_USER_ERROR);
}

しかし、マニュアルのサンプルコードを見てもすぐにロックできたかどうかの判定が返ってきそうに見えませんかね↓

$fp = fopen("/tmp/lock.txt", "w+");

if (flock($fp, LOCK_EX)) { // 排他ロックを行います
    fwrite($fp, "Write something here\n");
    flock($fp, LOCK_UN); // ロックを解放します
} else {
    echo "ファイルをロックできません!";
}

fclose($fp);

関連する投稿