<?php
class locks{
private $redis;
protected $lockid; //记录客户端加锁的ID
public function __construct(){
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$this->redis = $redis;
}
/**
* @param string $name 参数名
* @param int $exp 过期时间
* @param int $retry 重复次数
* @param int $sleep 等待时间
*/
public function lock($name = 'lock',$exp = 30, $retry = 10 , $sleep = 1){
$result = false;
while ($retry-- >= 0){
$value = md5(date("Y-m-d H:i:s"));
$result = $this->redis->set( $name , $value , ['NX' , 'EX'=>$exp] );
if ($result) {
$this->lockid[$name] = $value;
echo $name.' 成功获取到锁,正在执行' . "\n";
break;
}
echo $name.'加锁失败·· 正常尝试获取锁' ."\n";
sleep($sleep);
}
return $result;
}
/**
* @param $name
* @return mixed
* 删除锁
*/
public function unlock($name){
echo $name.' 正常执行解锁···' ."\n";
$lua = "
local key = KEYS[1]
local value = ARGV[1]
if(redis.call('get', key) == value)
then
return redis.call('del', key)
end";
return $this->redis->eval($lua, [$name, $this->lockid[$name]], 1);
}
}
// 申请分布式锁
$obj = new locks();
// 执行完成申请解锁
if($obj->lock($name = "lock_1")){
echo "执行结束,等待5s执行解锁操作···"."\n";
sleep(5);
echo "--------------------------"."\n";
$unlockResult = $obj->unlock($name);
if($unlockResult){
echo $name.' 解锁成功··' ."\n";
}
}
Redis申请分布式锁的命令,此命令符合原子性:
/**
* SET: Redis的String指令
* lock_name: 锁的名称
* unique_id: 锁的唯一校验
* NX: 只有当lock_name的值不存在的时候才能SET成功
* PX: 设置过期时间
*/
SET lock_name unique_id NX PX expire_time
分别执行,具体执行结果:
<?php
// 申请分布式锁
$obj = new locks();
// 执行完成申请解锁
if($obj->lock($name = "lock_1")){
echo "执行结束,等待5s执行解锁操作···"."\n";
sleep(5);
echo "--------------------------"."\n";
$unlockResult = $obj->unlock($name);
if($unlockResult){
echo $name.' 解锁成功··' ."\n";
}
}
客户端1:
客户端2:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。