如何用竞争条件强制三向死锁
How to force a three-way deadlock with race condition
到目前为止我有什么
我正在为死锁检测算法编写测试用例。我们想要检测 潜在的 死锁情况。目前,我们正在检查是否乱序获取了锁。
一个简单的双向测试如下:
- Thread1 获取 Lock1
- Thread2 获取 Lock2
- Thread1 阻止尝试获取 Lock2
- Thread2 阻止尝试获取 Lock1 <-- DEADLOCK
我们正确地将此检测为死锁。但是稍微延迟线程 2,它不会死锁,但我们正确地将其检测为 潜在 死锁:
- Thread1 获取 Lock1
- Thread1 获取 Lock2
- Thread1 释放两个锁
- Thread2 获取 Lock2
- Thread2 获取 Lock1
- 执行继续正常进行。
我们将此检测为潜在的死锁,因为 Thread1 获取这些锁的顺序与 Thread2 不同。所以如果时机刚刚好,也有可能出现僵局。
我被困在哪里
我正在围绕涉及三个或更多线程的死锁编写测试用例。我可以像这样轻松地强制三向死锁:
- Thread1 获取 Lock1
- Thread2 获取 Lock2
- Thread3 获取 Lock3
- Thread3 阻止获取 Lock2
- Thread2 阻止获取 Lock1
- Thread1 阻止获取 Lock3
同样,我们可以正确地将其检测为死锁。
但是我如何将此测试用例从保证死锁更改为潜在死锁?我将如何更改时间以继续正常执行?
提供不同加锁顺序不发生死锁的例子最简单的方法是及时将所有线程分开执行。您是针对双线程情况这样做的:第一个线程获取并释放所有锁,然后第二个线程才启动。对于三线程情况是一样的:你完全可以 运行 第一个线程,然后是第二个,然后是第三个。
更复杂的场景也是可能的:
- Thread1 获取 Lock1
- Thread3 获取 Lock3
- Thread1 阻止获取 Lock3
- Thread3 获取 Lock2
- Thread2 阻止获取 Lock2
- Thread3 完成并释放 Lock3 和 Lock2
- Thread2 获取 Lock2
- Thread2 阻止获取 Lock1
- Thread1获取Thread3释放的Lock3,完成并释放Lock1和Lock3
- Thread2 获取 Lock1,完成并释放锁
但是如果你想要演示,最简单的线程连续执行是最容易理解的。
到目前为止我有什么
我正在为死锁检测算法编写测试用例。我们想要检测 潜在的 死锁情况。目前,我们正在检查是否乱序获取了锁。
一个简单的双向测试如下:
- Thread1 获取 Lock1
- Thread2 获取 Lock2
- Thread1 阻止尝试获取 Lock2
- Thread2 阻止尝试获取 Lock1 <-- DEADLOCK
我们正确地将此检测为死锁。但是稍微延迟线程 2,它不会死锁,但我们正确地将其检测为 潜在 死锁:
- Thread1 获取 Lock1
- Thread1 获取 Lock2
- Thread1 释放两个锁
- Thread2 获取 Lock2
- Thread2 获取 Lock1
- 执行继续正常进行。
我们将此检测为潜在的死锁,因为 Thread1 获取这些锁的顺序与 Thread2 不同。所以如果时机刚刚好,也有可能出现僵局。
我被困在哪里
我正在围绕涉及三个或更多线程的死锁编写测试用例。我可以像这样轻松地强制三向死锁:
- Thread1 获取 Lock1
- Thread2 获取 Lock2
- Thread3 获取 Lock3
- Thread3 阻止获取 Lock2
- Thread2 阻止获取 Lock1
- Thread1 阻止获取 Lock3
同样,我们可以正确地将其检测为死锁。
但是我如何将此测试用例从保证死锁更改为潜在死锁?我将如何更改时间以继续正常执行?
提供不同加锁顺序不发生死锁的例子最简单的方法是及时将所有线程分开执行。您是针对双线程情况这样做的:第一个线程获取并释放所有锁,然后第二个线程才启动。对于三线程情况是一样的:你完全可以 运行 第一个线程,然后是第二个,然后是第三个。
更复杂的场景也是可能的:
- Thread1 获取 Lock1
- Thread3 获取 Lock3
- Thread1 阻止获取 Lock3
- Thread3 获取 Lock2
- Thread2 阻止获取 Lock2
- Thread3 完成并释放 Lock3 和 Lock2
- Thread2 获取 Lock2
- Thread2 阻止获取 Lock1
- Thread1获取Thread3释放的Lock3,完成并释放Lock1和Lock3
- Thread2 获取 Lock1,完成并释放锁
但是如果你想要演示,最简单的线程连续执行是最容易理解的。