PHP中的锁定文件是多么原子?

时间:2012-08-05 10:05:52

标签: php locking race-condition

我有一个PHP页面,一次只能由一个用户访问。这是一种“穷人的cron”:一个“Javascript”文件,在后台请求。目前我正在考虑创建一个这样的锁文件:

if(file_exists($lockfile) && filemtime($lockfile) + EXPIRES_AFTER > time() ) {
    die("// Page is locked.");
}

touch($lockfile);
// do stuff
unlink($lockfile);
echo "// Cron stuff was run";

但是我不确定file_existstouch调用之间是否存在非常短的机会窗口,其中另一个页面请求可以检查文件是否存在并且看到它不是'在那里。我们可能在这里谈论微秒,所以我想知道我真正需要开始担心的请求数量。

3 个答案:

答案 0 :(得分:2)

您编写的代码中没有原子性,所以是的,存在竞争条件。

答案 1 :(得分:2)

如果你想精确地 ,那么请使用不同的方法,因为检查和锁之间有一段时间。

两种可能的实施方式:

  1. 使用flock: https://secure.php.net/manual/en/function.flock.php

  2. 使用像STM这样的东西: 例如。打开锁定文件以追加,在其中写入内容,关闭句柄。然后读回文件,如果它只有你写入的文件,那么你就获得了锁。

  3. 除此之外,您的原始代码可能不会导致任何问题。

答案 2 :(得分:1)

您的代码有竞争条件。而是使用O_EXCL dio_open文件。如果文件已存在,则会失败。完成后取消链接。

唯一需要注意的是,如果系统或脚本在文件存在时崩溃,脚本将永远不会再运行。如果您对此感到担心,请检查文件的年龄(如果您未能创建它),如果它比脚本可能使用的时间长,请取消链接。

使用flock是另一种选择。