そのため、別のスクリプトやアプリケーションからの要求を受け入れて処理するためのスクリプトがあります。ただし、スクリプトで実行する必要があるタスクの 1 つは、各要求に一意の連続した「ID」をそれぞれに割り当てることです。
たとえば、アプリケーション A がスクリプトに 1000 のリクエストを送信し、同時にアプリケーション B がスクリプトに 500 のリクエストを送信しているとします。それぞれに 2001 ~ 3500 のように、1500 の固有の連番を付与する必要があります。
ただし、それらの間の順序は重要ではないため、次のように番号を付けることができます。
#2001 for 1st request from A (henceforth, A1)
#2002 for A2
#2003 for B1
#2004 for A3
#2005 for B2
...and so on...
その番号を保存するファイルと、次のような関数を使用して別のロックファイルを作成しようとしました:
private function get_last_id()
{
// Check if lock file exists...
while (file_exists("LAST_ID_LOCKED")) {
// Wait a little bit before checking again
usleep(1000);
}
// Create the lock file
touch("LAST_ID_LOCKED");
// Create the ID file for the first time if required
if (!file_exists("LAST_ID_INDICATOR")) {
file_put_contents("LAST_ID_INDICATOR", 0);
}
// Get the last ID
$last_id = file_get_contents("LAST_ID_INDICATOR");
// Update the last ID
file_put_contents("LAST_ID_INDICATOR", $last_id + 1);
// Delete the lock file
unlink("LAST_ID_LOCKED");
return $last_id;
}
ただし、このコードでは競合状態が発生し、1500 のリクエストを送信すると、最後の ID にかなりの数の欠落が発生します (たとえば、3500 ではなく 3211 にしか到達しません)。
私もこのように群れを使ってみましたが、役に立ちませんでした:
private function get_last_id()
{
$f = fopen("LAST_ID_INDICATOR", "rw");
while (true) {
if (flock($f, LOCK_SH)) {
$last_id = fread($f, 8192);
flock($f, LOCK_UN);
fclose($f);
break;
}
usleep($this->config["waiting_time"]);
}
$f = fopen("LAST_ID_INDICATOR", "rw");
while (true) {
if (flock($f, LOCK_SH)) {
$last_id = fread($f, 8192);
$last_id++;
ftruncate($f, 0);
fwrite($f, $last_id);
flock($f, LOCK_UN);
fclose($f);
break;
}
usleep($this->config["waiting_time"]);
}
return $last_id;
}
では、この状況の解決策を探すために他に何ができるでしょうか?
注:サーバーの制限により、セマフォなどのない PHP 5.2 に制限されています。