1

屏障是一种同步结构,其中一组进程全局同步,即集合中的每个进程到达屏障并等待所有其他进程到达,然后所有进程离开屏障。令集合中的进程数为 3,S 为具有常用 P 和 V 函数的二进制信号量。考虑以下 C 实现的屏障,其中行号显示在左侧。

void barrier (void) {    
    1: P(S);
    2: process_arrived++;
    3: V(S);
    4: while (process_arrived !=3);
    5: P(S);
    6: process_left++;
    7: if (process_left==3) 
       {
         8: process_arrived = 0;
         9: process_left = 0;
    10: }
    11: V(S);
 }

变量 process_arrived 和 process_left 在所有进程之间共享并初始化为零。在并发程序中,所有三个进程在需要全局同步时都会调用屏障函数。

上述实施会奏效吗?我认为如果立即连续使用两个屏障调用可能会导致死锁,因为进入屏障的第一个进程不会等到 process_arrived 变为零才继续执行 P(S)。

4

2 回答 2

1

提到有3个过程。让它成为P1,P2和P3。每个进程都会到达障碍,即它完成了它的第一部分代码。因此 process_arrived = 3。现在假设 P1 继续执行并离开屏障并使 process_left = 1。现在假设 P1 再次立即调用屏障函数。在这个阶段,process_arrived = 4。P1 现在等待。很快 P2 离开了屏障,这使得 process_left=2。现在 P3 离开了使 process_left=3 的障碍。“如果”条件为真,现在 process_arrived 和 process_left 重置为 0。我们知道 P1 正在等待。在这个阶段假设 P2 调用屏障函数,因此 process_arrived=1 并等待。P3 调用屏障函数,因此 process_arrived=2。所有进程都已到达障碍,但由于 process_arrived=2,所有进程都在等待。因此陷入僵局。

于 2014-12-29T13:15:17.833 回答
0

嗯...仅限于三个线程并且只有二进制信号量,我很想尝试使用三个信号量 A、B、C。A 控制对 process_arrived 计数的访问,B 和 C 用于第一个和第二个线程等待上。A 被初始化为 1,B & C 为 0。线程 1 得到 A,所以阻止 2 & 3 进入。process_arrived 上的开关导致线程 1 增加 process_arrived,释放 A 并等待 B。线程 2 获得 A,并且开关导致它增加 process_arrived,切换并因此释放 A 并等待 C。线程 3 获得 A,并且开关导致它向 B 发出信号,向 C 发出信号,将 process_arrived 设置为 0,向 A 发出信号并继续。

线程 1 和 2 不能通过 B 和 C,直到 3 向它们发出信号。当 B/C 由 3 发出信号时,1/2 可以运行但不能循环返回并进入屏障,直到 3 释放 A,此时屏障处于正确状态以再次充当屏障 - A 的计数为1、B 和 C 为零,process_arrived 为零。

于 2011-11-04T20:37:47.180 回答