$timeout = 5000;
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
do {
$microtime = microtime(true) * 1000;
$microtimeout = $microtime+$timeout+1;
// 上锁
$isLock = $redis->setnx('lock.count', $microtimeout);
if (!$isLock) {
$getTime = $redis->get('lock.count');
if ($getTime > $microtime) {
// 睡眠 降低抢锁频率 缓解redis压力
usleep(5000);
// 未超时继续等待
continue;
}
// 超时,抢锁,可能有几毫秒级时间差可忽略
$previousTime = $redis->getset('lock.count', $microtimeout);
if ((int)$previousTime < $microtime) {
break;
}
}
} while (!$isLock);
$count = $redis->get('count')? : 0;
// file_put_contents('/var/log/count.log.1', ($count+1));
// 业务逻辑
echo "执行count加1操作~ \n\n";
$redis->set('count', $count+1);
// 删除锁
$redis->del('lock.count');
// 打印count值
$count = $redis->get('count');
echo "count值为:$count \n";
//另外的方法
function lock($strMutex, $intTimeout) {
$objRedis = new Redis();
//使用setnx原子型操作加锁
$intRet = $objRedis->setnx($strMutex, 1);
if ($intRet) {
//设置过期时间,防止死任务的出现
$objRedis->expire($strMutex, $intTimeout);
return true;
}
return false;
}
function lock($strMutex, $intTimeout, $intMaxTimes = 0) {
$objRedis = new Redis();
//使用incr原子型操作加锁
$intRet = $objRedis->incr($strMutex);
if ($intRet === 1) {
//设置过期时间,防止死任务的出现
$objRedis->expire($strMutex, $intTimeout);
return true;
}
if ($intMaxTimes > 0 && $intRet >= $intMaxTimes && $objRedis->ttl($strMutex) === -1) {
//当设置了最大加锁次数时,如果尝试加锁次数大于最大加锁次数并且无过期时间则强制解锁
$objRedis->del($strMutex);
}
return false;
}
function lock($strMutex, $intTimeout) {
$objRedis = new Redis();
//使用setnx操作加锁,同时设置过期时间
$strRet = $objRedis->set($strMutex, 1, 'ex', $intTimeout, 'nx');
if ($strRet === 'OK') {
return true;
}
return false;
}