ファイルのロック

PHP で次のような簡単なアクセスカウンタを作りました。

<?php
  $fp = fopen("count.txt", "r+");
  $count = fgets($fp, 10);
  $count = $count + 1;
  fseek($fp, 0);
  fputs($fp, $count);
  fclose($fp);
?>

<p>あなたは <?php echo $count; ?> 人目のお客様です。</p>

しかし,これでは忙しいシステムでは数え間違えることがあります。 アクセスカウンタくらいなら問題ないかもしれませんが,切符を発行するシステムなどではオーバーブッキングが生じる可能性があります。

そこで,次のようにファイルを排他ロックします。

<?php
  $fp = fopen("count.txt", "r+");
  if (flock($fp, LOCK_EX)) { // 排他ロック
    $count = fgets($fp, 10);
    $count = $count + 1;
    fseek($fp, 0);
    fputs($fp, $count);
    flock($fp, LOCK_UN);     // ロック解除
  } else {
    echo "<p>ロックできません</p>";
  }
  fclose($fp);
?>

<blockquote>
<p>あなたは <?php echo $count; ?> 人目のお客様です。</p>
</blockquote>

ファイルをロックしている時間はなるべく短くする必要があります。 複数のファイル(一般にリソース)をロックする場合,下手にロックするとデッドロックが発生することがあります。

【課題】ファイルを読み書きする他のプログラムについても,ロックするように手直ししてください。


奥村晴彦

Last modified: 2007-05-24 19:52:12