php多进程死锁问题
- 互斥条件:至少有一种资源是排他性的,即一次只能被一个进程使用。
- 请求与保持条件:进程已经保持了至少一个资源,但在等待其他资源。
- 不可剥夺条件:资源不能被抢占,只有在进程完成后才会释放资源。
- 循环等待条件:多个进程形成一种循环等待对方已经持有的资源。
// 创建两个共享内存的进程
$pid1 = pcntl_fork();
$pid2 = pcntl_fork();
if ($pid1 == -1 || $pid2 == -1) {
die(‘Failed to fork’);
}
// 共享内存数据
$shm_id = shmop_open(1234, “c”, 0666, 1024);
$shm_data = 0;
// 进程1先获取锁1
if ($pid1 == 0) {
$lock1 = sem_get(1111);
sem_acquire($lock1);
// 进程1尝试获取锁2
$lock2 = sem_get(2222);
sem_acquire($lock2);
// 修改共享内存数据
shmop_write($shm_id, “1”, 0);
// 释放锁2
sem_release($lock2);
// 释放锁1
sem_release($lock1);
exit();
}
// 进程2先获取锁2
if ($pid2 == 0) {
$lock2 = sem_get(2222);
sem_acquire($lock2);
// 进程2尝试获取锁1
$lock1 = sem_get(1111);
sem_acquire($lock1);
// 修改共享内存数据
shmop_write($shm_id, “2”, 0);
// 释放锁1
sem_release($lock1);
// 释放锁2
sem_release($lock2);
exit();
}
// 父进程等待子进程结束
pcntl_waitpid($pid1, $status);
pcntl_waitpid($pid2, $status);
// 输出共享内存数据
$shm_data = shmop_read($shm_id, 0, 1024);
echo “共享内存数据:” . $shm_data . “\n”;
// 关闭共享内存
shmop_close($shm_id);
// 释放锁1和锁2
sem_remove($lock1);
sem_remove($lock2);
// 用户A
$productA = Product::find(1);
$productA->quantity = $productA->quantity – 1;
$productA->save();
// 用户B
$productB = Product::find(1);
$productB->quantity = $productB->quantity – 1;
$productB->save();
while ($retryTimes–) {
try {
// 获取资源
// 执行操作
break;
} catch (DeadlockException $e) {
// 等待一段时间再重试
sleep(1);
continue;
}
}
$lockTimeout = 10; // 锁的超时时间为 10 秒
while (true) {
// 尝试获取锁,如果成功则执行操作
$lockResult = Redis::set($lockKey, 1, ‘EX’, $lockTimeout, ‘NX’);
if ($lockResult === false) {
// 获取锁失败,等待一段时间再重试
sleep(1);
continue;
}
// 获取锁成功,执行操作
// 释放锁
Redis::del($lockKey);
break;
}
$lockTimeout = 10; // 锁的超时时间为 10 秒
while (true) {
// 尝试获取锁,如果成功则执行操作
$lockResult = Redis::set($lockKey, 1, ‘EX’, $lockTimeout, ‘NX’);
if ($lockResult === false) {
// 获取锁失败,等待一段时间再重试
sleep(1);
continue;
}
// 获取锁成功,执行操作
// 释放锁
Redis::del($lockKey);
break;
}
微信赞赏支付宝扫码领红包