(一)单标志法
想象有两个朋友,Alice 和 Bob,他们都想使用一间只有一台电脑的小屋进行工作。他们需要确保在任何时候只有一个人可以在小屋里使用电脑,以免打扰对方或发生争吵。于是,他们决定使用一个非常简单的标志系统:
标志(flag):小屋门口有一个小牌子,只有一面写着“Alice进入”,另一面是“Bob进入”。
当 Alice 想要使用电脑时,她会看牌子是否写着“Alice进入”。
- 如果牌子写着“Bob进入”,她就会在门外等待。
- 如果牌子是“Alice进入”,她就会进去工作。
- 工作完成后,翻动牌子,显示“Bob进入”。
当 Bob 想要使用电脑时,他也会看牌子是否写着“Bob进入”。
- 如果牌子写着“Alice进入”,他也会在门外等待。
- 如果牌子是“Bob进入”,他就会进去工作。
- 工作完毕后,他会将牌子翻转,显示“Alice进入”。
无论是 Alice 还是 Bob,在工作完离开小屋时,都会把牌子翻转回来,表示小屋现在轮到对方了。
优点:实现每次只允许一个进程进入临界区
缺点:进程必须交替进入临界区,如果轮到某一个进程时,该进程不进入临界区,则另外一个进程也无法进入临界区
(二)双标志先检查法
继续使用 Alice 和 Bob 想要使用一间只有一台电脑的小屋的例子,来解释双标志先检查法(Two-Flag Protocol with Prior Check)。
为了改进之前的单标志算法,Alice 和 Bob 决定使用两个标志来解决问题。每个人都有一个标志来表明自己是否想要进入小屋。他们还决定先设置自己的标志,然后检查对方的标志,以确保不会发生同时进入的情况。
设置标志:Alice 和 Bob 在想要进入小屋时,首先会设置自己的标志,表示他们想要进入。
检查对方的标志:在设置完自己的标志后,他们会检查对方的标志。如果发现对方也想要进入小屋,他们会礼貌地等待,直到对方完成。
Alice 想要使用电脑时:
- 她会先检查 Bob 的标志(bob_wants_to_enter),如果 Bob 也想要进入(bob_wants_to_enter = true),Alice 会等待。
- 如果 Bob 不想进入(bob_wants_to_enter = false),Alice会设置自己的标志(alice_wants_to_enter = true) ,进入小屋使用电脑。①
- 使用完电脑后,Alice 会清除自己的标志(alice_wants_to_enter = false)。
Bob 想要使用电脑时:
- 他会检查 Alice 的标志(alice_wants_to_enter),如果 Alice 也想要进入(alice_wants_to_enter = true),Bob 会等待。
- 如果 Alice 不想进入(alice_wants_to_enter = false),Bob设置自己的标志(bob_wants_to_enter = true),进入小屋使用电脑。②
- 使用完电脑后,Bob 会清除自己的标志(bob_wants_to_enter = false)。
优点:不用交替进入,可以连续使用。
缺点:如果两个进程连续执行到上文中的①和②时,双方都会进入临界区。
(三)双标志后检查法
Alice 和 Bob 各自有一个标志,表明自己想要进入小屋。他们会先设置自己的标志,表示他们想进入,然后检查对方的标志来决定是否可以进入临界区。
设置标志:
- Alice 和 Bob 想要进入小屋时,首先会设置自己的标志,表示他们想要进入。
- 检查对方的标志:在设置完自己的标志后,他们会检查对方的标志。
- 如果对方的标志也表示想要进入,他们会放弃自己的标志,并等待一段时间后再重试。
- 如果对方的标志没有设置,他们就可以进入小屋。
Alice 想要使用电脑时:
- 她会设置自己的标志(alice_wants_to_enter = true)。
- 然后她会检查 Bob 的标志(bob_wants_to_enter)。
- 如果 Bob 想要进入(bob_wants_to_enter = true),Alice 会放弃自己的标志(alice_wants_to_enter = false),稍后再重试。①
- 如果 Bob 不想进入(bob_wants_to_enter = false),Alice 就可以进入小屋使用电脑。
- 使用完电脑后,Alice 会清除自己的标志(alice_wants_to_enter = false)。
Bob 想要使用电脑时:
- 他会设置自己的标志(bob_wants_to_enter = true)。
- 然后他会检查 Alice 的标志(alice_wants_to_enter)。
- 如果 Alice 想要进入(alice_wants_to_enter = true),Bob 会放弃自己的标志(bob_wants_to_enter = false),稍后再重试。②
- 如果 Alice 不想进入(alice_wants_to_enter = false),Bob 就可以进入小屋使用电脑。
- 使用完电脑后,Bob 会清除自己的标志(bob_wants_to_enter = false)。
优点:不用交替进入,可以连续使用;先设置标志,后检查,避免同时进入
缺点:如果同时执行到①和②时,双方由于标志都为true,故而都会等待,进而卡住。
(四)Peterson算法
假设 Alice 和 Bob 还是使用小屋的场景,他们决定使用一个更复杂但更有效的系统:
- 标志:每个人都有一个标志,表示他们是否想进入小屋。
- 轮到谁:还有一个变量,表示轮到谁先使用小屋。
Alice:
- 她设置自己的标志,表示自己想进入小屋。
- 她设置“轮到谁”变量,让 Bob 先使用小屋。
- 如果 Bob 也想使用小屋,并且轮到 Bob 使用,Alice 就等待。
- 如果 Bob 不想使用小屋,或者轮到 Alice 使用,Alice 就进入小屋。
- 完成后,Alice 清除自己的标志,表示自己已离开小屋。
Bob:
- 他设置自己的标志,表示自己想进入小屋。
- 他设置“轮到谁”变量,让 Alice 先使用小屋。
- 如果 Alice 也想使用小屋,并且轮到 Alice 使用,Bob 就等待。
- 如果 Alice 不想使用小屋,或者轮到 Bob 使用,Bob 就进入小屋。
- 完成后,Bob 清除自己的标志,表示自己已离开小屋。
通过这种方法,Alice 和 Bob 能够公平地轮流使用小屋,不会发生冲突或长时间等待的情况。
优点:完美解决了上述方法的缺陷。