php 实现锁
锁的基本概念
锁在PHP中用于控制多进程或多线程对共享资源的访问,防止数据竞争和冲突。PHP作为脚本语言,通常以多进程方式运行,锁的实现主要依赖文件锁、数据库锁或扩展如Redis、Memcached等。
文件锁实现
文件锁通过flock()函数实现,适用于单机环境。以下是一个文件锁的示例代码:
$fp = fopen("lockfile.lock", "w+");
if (flock($fp, LOCK_EX)) { // 排他锁
// 临界区代码
flock($fp, LOCK_UN); // 释放锁
} else {
echo "获取锁失败";
}
fclose($fp);
数据库锁实现
MySQL提供了行级锁和表级锁。以下是通过MySQL实现的悲观锁示例:
$pdo = new PDO("mysql:host=localhost;dbname=test", "user", "pass");
$pdo->beginTransaction();
$stmt = $pdo->prepare("SELECT * FROM table WHERE id = 1 FOR UPDATE");
$stmt->execute();
// 临界区操作
$pdo->commit();
Redis分布式锁
Redis的SETNX命令可实现分布式锁。以下是PHP+Redis的实现:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$lockKey = 'resource_lock';
$randomValue = uniqid();
if ($redis->set($lockKey, $randomValue, ['NX', 'EX' => 10])) {
// 获取锁成功,执行业务逻辑
if ($redis->get($lockKey) == $randomValue) {
$redis->del($lockKey); // 释放锁
}
}
Semaphore扩展
PHP的sysvsem扩展提供信号量功能:
$semKey = ftok(__FILE__, 's');
$semId = sem_get($semKey);
if (sem_acquire($semId)) {
// 临界区代码
sem_release($semId);
}
注意事项
- 文件锁不适用于分布式系统
- 数据库锁可能影响性能
- Redis锁需处理死锁问题(通过过期时间)
- 信号量需要安装扩展且仅限Unix-like系统
选择锁的实现方式需根据具体场景(单机/分布式)和技术栈(是否有Redis等)决定。







