皮特森算法 软互斥 怎么不会导致饥饿了?我怎么看都觉得会饥饿啊 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
yangyaofei
V2EX    程序员

皮特森算法 软互斥 怎么不会导致饥饿了?我怎么看都觉得会饥饿啊

  •  
  •   yangyaofei
    yangyaofei 2016-03-06 21:09:16 +08:00 4480 次点击
    这是一个创建于 3587 天前的主题,其中的信息可能已经有所发展或是发生改变。

    wiki:https://zh.wikipedia.org/zh-cn/Peterson%E7%AE%97%E6%B3%95
    最近做题,遇到这个

    //flag[] is boolean array; and turn is an integer flag[0] = false; flag[1] = false; int turn; 

    P0:

    flag[0] = true; turn = 1; while (flag[1] == true && turn == 1) { // busy wait } // critical section ... // end of critical section flag[0] = false; 

    P1:

    flag[1] = true; turn = 0; while (flag[0] == true && turn == 0) { // busy wait } // critical section ... // end of critical section flag[1] = false; 

    如上代码, P1 执行完了的时候 turn=0,P0 可能在 while 处死循环,肯定无法设置 turn=1,所以不就饥饿了么?
    求解答

    8 条回复    2016-03-07 11:20:36 +08:00
    ppdg
        1
    ppdg  
       2016-03-06 22:11:10 +08:00
    flag[1] = false;了 P0 还死循环个毛啊
    yangyaofei
        2
    yangyaofei  
    OP
       2016-03-07 08:25:38 +08:00 via Android
    @ppdg 但是 turn 是 0 啊,怎么不是死循环……
    zado
        3
    zado  
       2016-03-07 08:36:40 +08:00
    即使 turn 是 0 也一样会跳出循环,&& 就是必须同时满足两边的条件才死循环。
    zado
        4
    zado  
       2016-03-07 08:42:38 +08:00
    哦,如果你说的是 P0 的话,那 turn 是 0 的话早直接就能跳出循环了,不管 flag[1] 是什么。
    soundofu
        5
    soundofu  
       2016-03-07 09:23:33 +08:00
    试试将 int turn; 声明为 volatile int turn; ?
    hxndg
        6
    hxndg  
       2016-03-07 09:54:35 +08:00
    俄,我个人理解哈:并不会饥饿阿,虽然计算机确实是在轮询,但是 p0 的阻塞条件除了 turn 之外,是由 p1 控制的,而 p1 会在进入阻塞之前释放掉对 flag[0]和 turn 的控制。换言之,两者都会在进入阻塞之前释放掉控制的信号量
    yangyaofei
        7
    yangyaofei  
    OP
       2016-03-07 10:55:15 +08:00 via Android
    @ppdg
    @hxndg
    @soundofu
    @zado
    啊啊啊啊,脑残了, while 那个地方看错了Σ(Д)Σ(Д)Σ(Д)Σ(Д)Σ(Д)
    bp0
        8
    bp0  
       2016-03-07 11:20:36 +08:00
    不会死锁,只不过延迟一段时间而已。

    如果 P1 执行完 turn = 0 后马上被 P0 抢占,那么 P0 会在 while 中等待。这时只有等 P0 的时间片用完以后, P1 才会被调度。 P1 被调度后继续往下运行,此时 turn 已经在 P0 中设置成 1 。所以 P1 不会在 while 处等待,而是继续运行后面的代码,当 P1 运行完成后会释放 flag[1],这样等 P0 再次被调度后,就能继续运行了。

    如果使用真正的锁, P0 在 while 时就会进入睡眠并释放 CPU ,而 P1 会马上运行。当 P1 完成工作并解锁后, P0 也会被马上再次调度并获得锁,然后继续运行后面的代码。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     800 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 20:50 PVG 04:50 LAX 12:50 JFK 15:50
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86