【问题标题】:Obtain exclusive read/write lock on a file for atomic updates获取文件的独占读/写锁以进行原子更新
【发布时间】:2014-01-16 17:47:40
【问题描述】:

我想要一个用作计数器的 PHP 文件。它将 a) 回显 txt 文件的当前值,并且 b) 使用排他锁递增该文件,因此在使用该文件时其他脚本无法对其进行读取或写入。

用户 A 将写入并增加此数字,而用户 B 请求读取文件。用户 A 是否可以锁定此文件,以便在用户 A 的写入完成之前没有人可以读取或写入它?

我过去使用过flock,但我不确定如何让文件等到它可用,而不是在它已被锁定时退出

我的目标是:

LOCK counter.txt; write to counter.txt;

同时

Read counter.txt; realize it's locked so wait until that lock is finished.

//

$fp = fopen("counter.txt", 'w+');
if(flock($fp, LOCK_EX)) {
    fwrite($fp, $counter + 1);
    flock($fp, LOCK_UN);
} else {
    // try again??
}

fclose($fp);

【问题讨论】:

  • flock() 的第三个参数指定了阻塞行为:php.net/flock。但默认情况下,在获得锁之前会阻塞,这在同一文档中也有提及。
  • 在使用这个的情况下,其他脚本会等到它不再被锁定吗?文档页面中没有太多详细信息。

标签: php locking


【解决方案1】:

来自文档:By default, this function will block until the requested lock is acquired

因此,只需在阅读器 (LOCK_SH) 和写入器 (LOCK_EX) 中使用羊群,它就可以工作了。 但是,我强烈反对在没有超时的情况下使用阻塞群,因为这意味着如果出现问题,那么您的程序将永远挂起。为了避免这种情况,请使用这样的非阻塞请求(同样,它在文档中):

/* Activate the LOCK_NB option on an LOCK_EX operation */
if(!flock($fp, LOCK_EX | LOCK_NB)) {
    echo 'Unable to obtain lock';
}

并将其包装在一个 for 循环中,在失败的 n 次尝试(或总等待时间)后休眠和中断。

编辑:您还可以查找一些使用示例here。这个类是ninja-mutex 库的一部分,你可能也会感兴趣。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-30
    • 2020-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-20
    • 1970-01-01
    相关资源
    最近更新 更多