Operating system 测试和设置指令中的有界等待

Operating system 测试和设置指令中的有界等待,operating-system,synchronization,critical-section,Operating System,Synchronization,Critical Section,为了保证测试和设置指令中的有界等待,以下是操作系统手册Galvin-中给出的代码: do { 1 waiting[i] = true; 2 while (waiting[i] && test_and_set(&lock)) ; 3 waiting[i] = false; /* critical section */ 4 j = (i + 1) % n

为了保证测试和设置指令中的有界等待,以下是操作系统手册Galvin-中给出的代码:

        do {
    1         waiting[i] = true;
    2         while (waiting[i] && test_and_set(&lock)) ;
    3         waiting[i] = false;

    /* critical section */

    4         j = (i + 1) % n;
    5         while ((j != i) && !waiting[j]) 
    6         j = (j + 1) % n; 
    7         if (j == i) 
    8          lock = false; 
    9         else
    10         waiting[j] = false;

    /* remainder section */
         } while (true);
我得到了完整的代码并得出结论

如果出现以下情况之一,流程p_i将处于关键部分: Waiting[i]=false或test_and_set(&lock)=false,这确保了锁之前是false的。所以,退出部分要么将Waiting[j]或lock设置为FALSE

但我有一些疑问-:

  • 如果在退出部分发现相同的流程再次请求关键部分,即

        if j==i
    
  • 然后根据代码,该进程必须从第2行开始执行,即将执行

           test_and_set(&lock))
    
    在while循环中,找到test_和_set(&lock))的返回值为false,然后移动到critical section。我的疑问是,如果相同的进程想要在critical section中,是否有必要从第2行开始执行它

    2.现在我想做以下排列,并想检查可能的结果。我想交换第8行和第10行

    • 在第8行,如果我

       waiting[j]=false;
      
      然后,它也将移动到临界部分,即使现在lock=true

    • 在第10行,如果我

       waiting[j]=false;
      
      锁=假

      然后,它(进程p_j)将移动到临界段,即使等待[i]=true,我认为这会更好,因为在while循环由于test_和_set(&lock)=false而中断之后,第3行将分配等待[i]=false。 另一方面,如果我进行此更改,则必须执行测试和设置(&lock),这非常耗时

    我对第二点的假设正确吗

    第1点的正确理由是什么


    关于第1点,谢谢你:

    我的疑问是,若同样的流程想要进入关键部分,那个么 必须从第2行开始执行

    进程基本上是一个正在执行的程序。进程不能选择下一步执行哪个指令。控制流决定了这一点。代码控制(即流程本身)表明,如果流程成功进入关键部分,并且再次想要进入关键部分,然后它将首先执行
    第4行到第10行
    ,然后执行剩余部分,并且必须从第1行开始执行

    关于你的第2点

    现在我想做下面的排列,并检查可能的结果 结果。我想交换第8行和第10行

    如果交换行,有界等待条件将不再存在

    证明

    假设只有一个进程
    p(i)
    请求访问关键部分,并成功进入。所以

    lock = true and waiting[i] = true
    
    因为只有这样,它才能从for循环中走出来。现在它从第4行开始执行

    然后j取以下值:

    i + 2 , i + 3, ......0 , 1 , 2 , 3 , 4....i
    
    由于%operator,发生了值的环绕。由于没有其他进程请求进入关键部分,
    等待[j]=false
    for
    j!=我

    因此,当
    j
    等于
    i
    时,
    while((j!=i)和&!waiting[j])
    条件变为假,现在我们在
    第7行。新守则是:

    if (j == i) 
      waiting[j] = false;
    else
      lock = false; 
    

    现在,如果任何进程请求进入临界区,则
    同时(等待[i]&&test_和_设置(&lock))的计算结果总是
    true
    ,因为
    lock是true
    waiting[i]
    也是
    true
    ,它会被卡在自旋锁中。不会有任何进展

    这种代码是荒谬的。一定还有其他的地方。@user3344003你能提到行号吗?@user3344003检查一下@sourav希望清楚。@:Summet谢谢你对第1点的澄清,但第2点你写了>lock=true和waiting[i]=true,我同意lock=true,但wating[i]=true如何?我没有看到任何一行使“wating[i]=true”。@sourav waiting[i]=true是因为第1行。任何希望进入临界段的工艺P(i)必须通过第1行。简单的说@:Sumeet“假设只有1个进程P(i)发出访问关键部分的请求,并且它成功地进入了。”我怀疑如果一个进程P_i成功地进入了CS,那么根据第3行,等待[i]=假。我的意思是,当其他进程P(i')进入时,等待[i]=真试图进入临界区,此I'与I不同。所以我基本上说的是第二个进程,当我说等待[i]是真的时,它试图进入关键部分(在第一个进程成功进入并离开之后)。