Locker::lock 有bug啊?没bug 多进程的问题 已解决

lsmir2

问题描述

截图
截图

程序代码或配置

        $ip = $request->getRealIp();
        $key =(string) ip2long($ip);
        Cache::Incr($key);  //1                                  //再次刷新 3
        Locker::lock($key); //无锁则加锁继续            //已经加锁了    阻塞失败
        Cache::Incr($key);  //2                                 //这里是4
        return  Cache::Get($key); //输出2                //输出4,甚至是5 锁失效..

重现问题的步骤

浏览器打开接口然后一直点刷新..

操作系统环境及workerman/webman等具体版本

Workerman/5.1.3 PHP/8.3.21 (JIT off) Darwin/23.6.0
--------------------- WORKERS ----------------------
event-loop proto user worker listen count state
fiber tcp lsmir2 webman http://0.0.0.0:8787 2 [OK]
event tcp lsmir2 monitor none 1 [OK]
event tcp lsmir2 plugin.webman.redis-queue.consumer none 2 [OK]

327 2 1
2个回答

lsmir2

手搓一个多进程锁 感谢兔子大佬的WebmanSharedCache插件真的很好用.

<?php
namespace app\common;
use Workbunny\WebmanSharedCache\Cache;
class Locker
{
    /**
     * 多进程锁
     * @param string $key  锁的键名
     * @param int $ttl     锁过期时间,单位秒
     * @return bool
     */
    public static function lock(string $key, int $ttl = 2): bool
    {
        $lockKey = "lock_{$key}";
        if (!Cache::get($lockKey)) {
            Cache::set($lockKey, 1,  ['EX' => $ttl]);
            return true;
        }
        return false;
    }

    /**
     * Unlock.
     *
     * @param string $key
     * @return bool
     */
    public static function unlock(string $key): bool
    {
        $lockKey = "lock_{$key}";
        if (Cache::get($lockKey)) {
            Cache::Del($lockKey);
            return true;
        }

        return false;
    }
}
  • ak47f16200 8天前

    多进程下没问题?

  • lsmir2 6天前

    支持多进程,Workbunny\WebmanSharedCache\Cache 是跨进程缓存

qq7467466

Windows环境下locker不生效的, 需要在linux下进行测试
具体看这个: https://www.workerman.net/q/10238

  • lsmir2 22天前

    多进程的问题,你看源码就知道了有个静态数组.

🔝