以下是一个简单的示例代码,用于演示如何使用PHP的Redis扩展实现分布式锁:
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 加锁
function acquireLock($lockName, $timeout = 10) {
global $redis;
$startTime = time();
$expireTime = $startTime + $timeout;
$lockValue = getUniqueLockValue();
while (true) {
$result = $redis->set($lockName, $lockValue, ['nx', 'ex' => $timeout]);
if ($result) {
return true;
}
// 检查锁是否已超时
if (time() > $expireTime) {
return false;
}
// 延迟一段时间后重试
usleep(1000);
}
}
// 释放锁
function releaseLock($lockName) {
global $redis;
$redis->del($lockName);
}
// 生成唯一的锁值
function getUniqueLockValue() {
return uniqid();
}
$lockName = 'my_lock';
// 尝试获取锁
if (acquireLock($lockName)) {
// 成功获取到锁
// 在此处执行需要互斥访问的代码
// 释放锁
releaseLock($lockName);
} else {
// 未获取到锁
echo 'Failed to acquire lock!';
}
?>
这个示例代码通过acquireLock()
函数尝试获取锁,如果获取成功,则执行需要互斥访问的代码,然后通过releaseLock()
函数释放锁。如果获取不成功,则输出一条错误消息。
在acquireLock()
函数中,首先生成一个唯一的锁值,并在Redis中尝试设置这个锁值,使用nx
选项表示仅在键不存在时才设置成功,使用ex
选项设置锁的过期时间。如果设置成功,则表示获取到了锁,函数返回true
;如果设置不成功,则进入一个循环,每次等待一段时间后重新尝试获取锁,直到超时时间到达或者成功获取锁。如果超过了超时时间仍未获取到锁,则返回false
。
在releaseLock()
函数中,通过调用Redis的del()
方法删除锁键。
请注意,这只是一个简单示例,用于演示如何使用PHP Redis扩展实现分布式锁。在实际应用中,还需要考虑更多的细节,例如处理死锁、处理锁的异常情况等。