php锁实现
PHP 锁实现方法
在 PHP 中实现锁机制可以通过多种方式,以下是常见的几种方法:
文件锁(flock)
使用 PHP 的 flock 函数可以对文件进行加锁,适用于单机环境下的进程同步。
$fp = fopen("lockfile.lock", "w+");
if (flock($fp, LOCK_EX)) { // 排他锁
// 临界区代码
flock($fp, LOCK_UN); // 释放锁
} else {
// 获取锁失败处理
}
fclose($fp);
数据库锁
利用数据库的行锁或表锁机制实现并发控制。
MySQL 示例:
// 开始事务
$pdo->beginTransaction();
// 获取行锁
$stmt = $pdo->prepare("SELECT * FROM table WHERE id = ? FOR UPDATE");
$stmt->execute([$id]);
// 执行需要同步的操作
$pdo->commit(); // 释放锁
Redis 锁
通过 Redis 的 SETNX 命令实现分布式锁。
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$lockKey = 'resource_lock';
$randomValue = uniqid();
$expireTime = 10; // 秒
// 尝试获取锁
if ($redis->set($lockKey, $randomValue, ['NX', 'EX' => $expireTime])) {
try {
// 临界区代码
} finally {
// 确保只有锁的持有者才能释放
if ($redis->get($lockKey) == $randomValue) {
$redis->del($lockKey);
}
}
}
Semaphore 信号量
在支持 System V 信号量的系统上可以使用:
$semKey = ftok(__FILE__, 'a');
$semId = sem_get($semKey);
if (sem_acquire($semId)) { // 阻塞获取
// 临界区代码
sem_release($semId);
}
锁的最佳实践
- 总是设置锁的超时时间,避免死锁
- 考虑锁的粒度,不要过度使用全局锁
- 分布式环境下使用 Redis 或 ZooKeeper 等专门方案
- 释放锁时要确保只有锁的持有者才能释放
- 考虑锁的可重入性需求
选择哪种锁实现取决于具体应用场景,单机环境文件锁足够简单,分布式系统则需要 Redis 等方案。







