V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
amiwrong123
V2EX  ›  程序员

怎么理解操作系统的 Peterson 算法的特殊情况

  •  
  •   amiwrong123 · 2022-04-10 00:46:08 +08:00 · 1209 次点击
    这是一个创建于 960 天前的主题,其中的信息可能已经有所发展或是发生改变。

    1649519892_1_.jpg 我理解正常一个进程的程序是这样写的:

    int number;
    enter_region(number);
    这里是临界区的操作;
    leave_region();
    

    当进程 0 执行了 enter_region(0);,但还没有执行 leave_region 时。此时进程 1 去执行 enter_region(1);,会发现:

    • 不仅turn == process成立了(我理解,这代表当前进程正在请求)
    • 而且 interested[other] == True 所以进程 1 要进入这个无限循环,直到进程 0 执行 leave_region 。

    1649522343.jpg 但是现在有这种特殊情况:

    • 都运行到 while 语句前时,turn 这个全局变量被设为 1 ,因为进程 1 后执行
    • 然后进程 0 ,由于不满足turn == process&&interested[other] == True的第一个条件,直接短路,然后不执行这个循环,然后进程 0 进入到 临界区。
    • 我的疑惑点在于:为什么turn == process不成立,就直接短路,然后就让当前进程去临界区了呢(虽然确实是正常工作了,这之后,进程 0 进入临界区,进程 1 则无限循环了)?总感觉有点反直觉,不知道该怎么解释
      • 感觉正常情况的话,应该是如上的:turn == process成立,但interested[other] == True不成立。
    5 条回复    2022-04-10 17:47:27 +08:00
    churchmice
        1
    churchmice  
       2022-04-10 01:18:42 +08:00 via Android
    不会啊,进程 0 做完之后对于进程 1 的 while 条件 interested[other] 就不成立了,进程 1 就会跳出 while 去 critical region 了
    amiwrong123
        2
    amiwrong123  
    OP
       2022-04-10 11:28:47 +08:00
    @churchmice #1
    是的,确实如你所说,能够正常工作的。

    我的纠结点在于:
    - 我觉得应该既要判断 turn 的值,也要判断 interested 数组的值。两个都判断完事之后,才可以去临界区。
    - 但是我帖子里这种特殊情况的话,进程 1 只判断 turn == process ,后面那个条件就直接短路了(它就根本没判断 interested 数组)

    但是,后来我一想。既然执行到 turn == process ,说明 interested 数组的自己索引位置已经变成 True 。然后 turn == process 不成立,说明另一个进程也至少执行到了 trun = process 这句,那么另一个进程肯定会进入无限循环,所以 这里可以短路判断。
    heiher
        3
    heiher  
       2022-04-10 15:28:57 +08:00 via Android
    刚执行过 turn = self_process ,随后的判断 turn == self_process 就不成立,则说明一定有其它进程也执行了 turn = process ,但也一定会卡在 interested[other] == true 条件上,所以当前线程可以安全进入临界区。另外,挺有意思的是这个算法在 x86 的内存模型上需要使用内存屏障指令。
    amiwrong123
        4
    amiwrong123  
    OP
       2022-04-10 16:54:25 +08:00
    @heiher #3
    应该在哪里加 内存屏障阿,另外,应该加什么内存屏障阿
    heiher
        5
    heiher  
       2022-04-10 17:47:27 +08:00 via Android
    @amiwrong123 需要防止 Store interested[process] 乱序到 Load turn 之后:

    interested[process] = TRUE;
    turn = process;
    storeload_barrier (mfence on x86)
    while (turn == process && interested[other] == TRUE);
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   935 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 22:10 · PVG 06:10 · LAX 14:10 · JFK 17:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.