编辑代码

<?php

var_dump(PHP_OS);

var_dump(PHP_VERSION);

function ulock(callable $cb)
{
    $lockFile = 'limit.lock';
    do {
        // 以二进制读追加的方式打开
        $fp = fopen($lockFile, 'ab+');
        // 加排他锁,不要阻塞
        if (!flock($fp, LOCK_EX | LOCK_NB)) {
            var_dump('获取锁失败');
            break;
        }
        // 当前时间
        $now = time();
        // 读出文件里面保存的时间
        $timestamp = (int)fgets($fp);
        // 如果获取到的时间大于等于当前的,就跳出
        if ($timestamp >= $now) {
            // 记得解锁
            flock($fp, LOCK_UN);
            break;
        }
        // 执行逻辑
        $cb($now);
        // 把文件清空(因为是 ab+ 打开的)
        ftruncate($fp, 0);
        // 写入当前时间
        fwrite($fp, $now);
        // 解锁
        flock($fp, LOCK_UN);
    } while (false);

    // 关闭文件
    fclose($fp);
}

for ($i = 0; $i < 20; $i++) {
    ulock(function ($now) {
        var_dump($now);
    });
    // 随机等待时间
    usleep(mt_rand(1, 3) * 1e5);
}