php flock 是已经不能用了还是我姿势不对?

shuff
  • 234

用户注册卡顿会出现并发问题(重复)

只想用简单的文件锁实现并发阻塞功能

我是想同一个用户出现连续请求注册接口时,重复的请求直接返回失败,锁代码如下

<?php
for ($i=0; $i < 5; $i++) {
    // 我已经手动创建了lock.txt
    $fp = fopen('/tmp/lock.txt', 'r+');

    /* Activate the LOCK_NB option on an LOCK_EX operation */
    if(!flock($fp, LOCK_EX | LOCK_NB)) {
        echo 'Unable to obtain lock';
        exit(-1);
    }
    sleep(10);
    /* ... */
    // 解锁
    flock($fp, LOCK_UN);    
    // 释放锁定
    fclose($fp);
    echo "success\n";
}

经过测试,无论如何都是不会进入 Unable to obtain lock 这一步的,这是什么情况?
难道flock不能用了么。。
下面是使用docker环境测试的结果
docker应该就算是linux环境了吧。。

PHP 8.0.8 (cli) (built: Jul 22 2021 02:16:23) ( NTS
Copyright (c) The PHP Group
Zend Engine v4.0.8, Copyright (c) Zend Technologies

image.png

回复
阅读 137
1 个回答
✓ 已被采纳
  • 首先, LOCK_NB 这个标识在 Windows 下是不支持的,只会阻塞。
  • 其次,根据文档的说法 5.3.2 | 文件资源句柄关闭时不再自动解锁。现在要解锁必
  • 需注意,如果你使用 r+ 打开文件,就要确保文件一定存在,否则就会打开失败。文件句柄返回 false
  • 你的原代码中, sleep 后面缺少一个分号

image.png

$ docker run -it php bash
root@a16788b146f8:/# php -v
PHP 8.0.8 (cli) (built: Jul 22 2021 02:16:23) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.8, Copyright (c) Zend Technologies
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
你知道吗?

宣传栏