用于进程同步的烘焙算法

时间:2014-11-07 18:53:28

标签: synchronization

do { 
     choosing[i] = true; 
     number[i] = max(number[0], number[1], …, number [n – 1])+1; 
     choosing[i] = false; 
     for (j = 0; j < n; j++) { 
     while (choosing[j]); // 
     while ((number[j]!= 0) && (number[j],j)<(number[i],i))); 
     } 
     critical section 
     number[i] = 0; 
     remainder section 
    } while (1); 

请帮助我知道选择在这做什么。我检查了所有可以生成以了解其用途的条件。但它似乎没有任何区别。

请通过提供案件帮助我。

1 个答案:

答案 0 :(得分:3)

当数字[i]被更新为大于数字数组中的所有其他值时,选择[i]为真 - 线程正在采用的新票证值。在for循环的主体中,代码首先等待选择[j]为false,这表示线程号j选择了该轮的票。如果线程j继续执行而线程i还没有进入临界区,那么数字[i]不会改变,所以:

如果线程j仍处于同一轮并且尚未完成关键部分,则数字[j]是最大计算的结果,该计算可能会或可能不会采用数字[i的当前值考虑到,取决于线程i和j的执行的交错。 如果线程j在余数部分中,则数字[j]为0。 如果线程j已经开始新一轮,则其数字[j]是考虑了数字[i]的当前值的最大计算的结果,因此数字[j]>数[i]中。 在第一种情况下,线程i和j同时运行它们的for循环;只有其中一个将赢得(数字[j],j)&lt;(数字[i],i)比较并进入临界区,另一个将等待获胜者的数值变为可接受再次。在第二种情况下,线程j不竞争临界区。在第三种情况下,线程j具有更高的数字并且将在其自己的for循环中等待,而线程i没有重置其数字[i]值。

选择数组解决了number []值计算中缺乏原子性的问题。如果它被删除,那么你可以让两个线程同时计算相同的值,并且每个线程在测试时发现它具有较小的值。只需两个线程就可以发生这种情况(我使用符号k.tmpX来指定线程k的本地存储):

最初:数字[1] =数字[2] = 0

thread 1                                   thread 2
//choosing[1]=true
1.tmp1 = number[1]
1.tmp2 = number[2]
                                           //choosing[2]=true
                                           2.tmp1 = number[1]
                                           2.tmp2 = number[2]
                                           number[2] = max(2.tmp1,2.tmp2)+1 = 1
                                           //choosing[2]=false
                                           //while (choosing[1]) {}
                                           while (number[1]≠0 &&
                                                  (number[1],1)<(number[2],2)) {}
                                           critical section ...
number[1] = max(1.tmp1,1.tmp2)+1 = 1
//choosing[1]=false
//while (choosing[2]) {}
while (number[2]≠0 &&
       (number[2],2)<(number[1],1)) {}
critical section ...
                                           critical section ...

两个线程计算了相同的票号。在这种情况下,烘焙算法使用线程号来确定优先级。但是,线程2在线程1仍在准备时决定关键线程,而线程1在决定是否进入关键部分时却看到线程2的新票号,但是根据线程2计算了自己的票号。旧机票号码。因此,线程1错误地进入了关键部分。

选择数组通过阻止线程2进入临界区来解决此问题。由于线程1在线程2准备进入临界区时计算其票号,因此线程2将阻塞(选择[1]){},之后它将看到数字[1]的更新值和允许线程1首先进入临界区,而线程2等待(数字[1]≠0&amp;&amp;(number [1],1)&lt;(number [2],2)){}。< / p>