所以我有一个脚本用于接受和处理来自另一个脚本和/或应用程序的请求。但是,我的脚本必须完成的一项任务是为每个请求分配一个唯一的、连续的“ID”。
例如,假设应用程序 A 向我的脚本发出 1000 个请求,同时应用程序 B 向我的脚本发出 500 个请求。我必须给他们 1500 个唯一的序列号,比如 2001~3500 给他们每个人。
然而,它们之间的顺序无关紧要,所以我可以给它们这样的数字:
#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 将有很多缺失,(例如,只达到 3211 而不是 3500)。
我也尝试过像这样使用羊群,但无济于事:
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,没有信号量之类的东西。