質問

私はJava、C、C ++に精通しており、特定の時点で1つのスレッドのみがリソースにアクセスするように制御する方法があります。今は似たようなものを探していますが、PHP 5.xを使用しています。

1つの例で問題を定式化するには:

ページロードカウンタの値である数値のみを保存するASCIIファイルがあります。アプリケーションの展開時に、ファイルは単に0を保持します。アクセスごとに値が1ずつ増加します。目標は、ページの読み込みを追跡することです。

この問題は、カウンターを含むページに多くのユーザーが同時にアクセスしている場合に発生します。スレッドAが現在の値を読み取り、11とすると、Bと呼ばれる別のスレッドが値を読み取ります。まだ11です。その後、最初のスレッドAは読み取り値をインクリメントし、ファイルに12を書き込み、閉じます。次に、2番目のスレッドBが読み取り値をインクリメントします。これは11でしたが、12を取得してファイルに書き込みます。値12はファイルに保存されますが、実際には13でなければなりませんでした。

別のプログラミング言語では、ミューテックスを使用してこれを解決していました。モジュールの一部として、ミューテックス、共有メモリ、その他の機能があることを理解しています。しかし、「ほとんどのサーバー」で動作するソリューションが欲しいです。そこに。プラットフォームに依存しません。最も安価なWebホストにインストールされます。この問題の解決策はありますか?存在しない場合、データベースを使用することはオプションではない場合、どの方法を使用しますか?

役に立ちましたか?

解決

PHPのflockのバリアントを試すことができます( http://www.php.net/flock

似たようなものを想定します(これは、ファイル/tmp/counter.txtが既に存在し、ファイル内にカウンターがあることを前提としています):

<?php

$fp = fopen("/tmp/counter.txt", "r+");

echo "Attempt to lock\n";
if (flock($fp, LOCK_EX)) {
  echo "Locked\n";
  // Read current value of the counter and increment
  $cntr = fread($fp, 80);
  $cntr = intval($cntr) + 1;

  // Pause to prove that race condition doesn't exist
  sleep(5);

  // Write new value to the file
  ftruncate($fp, 0);
  fseek($fp, 0, SEEK_SET);
  fwrite($fp, $cntr);
  flock($fp, LOCK_UN); // release the lock
  fclose($fp);
}

?>

他のヒント

PHPのflock()関数は、進むべき道です。ただし、ファイルへの all アクセスは、最初にflock()を呼び出して保護する必要があります。 PHPは、明示的に呼び出しを行わない限り、ファイルがロックされているかどうかをチェックしません。

この概念は、ミューテックス(共有リソースの保護など)とほぼ同じですが、特別な強調を行うには十分に重要です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top