我想我明白了……最大的提示是“在初始化阶段只能进行空闲”。
首先,对互斥锁的限制是您必须在锁定的同一线程中解锁。因此unlock(),线程中的每个线程都必须与 a 配对lock(),并且我们必须拥有相等数量的互斥锁(否则我们会陷入死锁)。
这意味着我们可以防止线程多次打印的唯一方法是确保每个线程始终拥有至少一个互斥体。如果线程 B 在任何时候释放了它所有的互斥体,然后 CPU 切换到线程 A,它就可以无限期地运行。
我们不能用 2 个没有死锁的互斥锁来做到这一点,但我们可以用 3 个来做到这一点。
父线程:
bool initDone = false;
lock(m1);
lock(m2);
spawnChild();
while (!initDone)
sleep();
while (true) {
print("Parent");
unlock(m1);
lock(m3);
unlock(m2);
lock(m1);
unlock(m3);
lock(m2);
}
子线程:
lock(m3);
initDone = true;
while (true) {
lock(m1);
unlock(m3);
lock(m2);
print("Child");
unlock(m1);
lock(m3);
unlock(m2);
}
我们从父级拥有锁 1 和 2,子级拥有 3 开始。然后他们轮流释放和获取锁:父级给子级锁 1,子级给父级锁 3,父级给子级锁 2,子级给锁 1父母,父母给孩子锁3,孩子给父母锁2,重复。
一个有趣的问题;我敢打赌,您现在看到了条件变量的吸引力,因为它们使这一点变得微不足道。