PHPのLOCK_NBの挙動について

flock関数の第2引数に使用できるフラグに、"LOCK_NB"というものがある。

flock($fp, LOCK_EX | LOCK_NB);

のように、他のフラグのビットマスクとして使うことができる。
PHP.netによると、このフラグの意味は

It is also possible to add LOCK_NB as a bitmask to one of the above operations if you don't want flock() to block while locking. (not supported on Windows)

とあり、私の英語力だと

  • 1つ目のプロセス⇒LOCK_NBを使用してflock、2つ目のプロセス⇒直ちに失敗

なのか、

  • 1つ目のプロセス⇒LOCK_NBを【使用せず】flock、2つ目のプロセス⇒LOCK_NBを使用してflockを試みると、直ちに失敗

なのかがよく分からなかった。

なので、以下のようなスクリプトを作成して試してみた。

lock.php

$fp = fopen("lock.txt", "r");
var_dump($fp);
$result = flock($fp, LOCK_EX);
var_dump($result);
if ($result) {
sleep(10);
}
var_dump(flock($fp, LOCK_UN));
var_dump(fclose($fp));

lock_NB.php

$fp = fopen("lock.txt", "r");
var_dump($fp);
$result = flock($fp, LOCK_EX | LOCK_NB);
var_dump($result);
if ($result) {
sleep(10);
}
var_dump(flock($fp, LOCK_UN));
var_dump(fclose($fp));

で、結果どうなったかというと、

  • lock.php ⇒ lock_NB.php の順だと、直ちに失敗する。
  • lock_NB.php ⇒ lock.php の順だと、ロックが解除されるまで待つ

という動作になった。
つまり、LOCK_NBは、
「ファイルのロックに失敗した場合、【自分自身を】直ちに失敗させるフラグということになる」