以下程序由3个并发进程和3个二进制信号量组成 信号量被初始化为S0 = 1 S1 = 0 S2 = 0
过程P0:
while(1)
{
wait (S0);
print '0';
release (S1);
release (S2);
}
流程P1:
wait(S1);
release (S0);
流程P2:
wait(S2);
release (S0);
处理PO打印的次数为“0”??
(A)至少两次(b)完全tWlce(c)完全三次(d)恰好一次
在此我有一个混乱,即进程P1和P2将执行一次或者它们将在执行一次后继续,因为它们没有像循环那样的循环,如果它们只执行一次那么根据我的答案应该是(b),如果他们将再次执行,那么答案将是(A)
请提前帮助谢谢
答案 0 :(得分:3)
最初P0
将执行,因为只有S0=1
。它将打印单个0。
现在当S1
和S2
被P0
发布时,其中任何一个都可以被执行。
让我们假设P1执行并释放S0(现在S0的值为1)。
现在有两种可能性P0
或P2
可以执行。
让我们执行P2
执行并释放S0
,所以最后P0执行并打印0(表示两个0)
但如果P0
在P2
之前执行,那么将打印总共3 0个(一个在P0
,然后P2
,这会释放S0
所以{{1再次执行。)
所以完美答案至少是两个0。
答案 1 :(得分:1)
解决方法如下:
只有进程P0才能先执行。这是因为进程P0使用的信号量,即S0的初始值为1.现在当P0调用S0等待时,S0的值变为0,这意味着S0已被P0占用。就过程P1和P2而言,当它们分别在S1和S2上调用wait时,它们无法继续,因为信号量已经被初始化为取即0,所以它们必须等到S1和S2被释放!
P0先行并打印0.现在接下来的陈述将释放S1和S2!当S1被释放时,过程P1的等待结束,因为S1的值上升1并且未被标记。 P1取S1并使S1成为。过程P2也是如此。
现在,only one of P1 or P2 can execute, because either of them can be in the critical section at a given time
..假设P2执行。它释放S0并终止。
让P1执行下一步.. P1开始释放S0并终止。
Now only P0 can execute because its in a while loop whose condition is set to true, which makes it to run always.
P0第二次执行打印并释放S1和S2。但是P1和P2已经被终止,因此P0将永远等待S0的发布。
这是第二个打印0次的解决方案:
P0开始,打印0和释放S1和S2。
让P2执行。 P2启动,释放S0并终止。在此之后,只能执行P0或P1。
让P0执行。第二次打印0并释放S1和S2。此时只有P1可以执行。
P1开始,释放S0,P1终止。此时只有P0可以执行,因为它在一个while循环中,其条件设置为true!
P0开始,第3次打印0并释放S1和S2。然后它等待有人释放从未发生过的S0。
所以答案恰好是两次或者恰好三次,也可以说是“atleast twice
”!
请告诉我,我在哪里错了!
有关信号量的更多问题,请参阅this
答案 2 :(得分:0)
我假设wait()递减信号量并阻塞它变为< = 0,而release会增加计数器并唤醒下一个进程。
鉴于您的代码,P1和P2执行一次(它们周围没有循环)。这意味着每个触发一次S0。并且当P0在每次打印之前在S0上等待时,它最终将打印'0'两次。
要检查的另一件事是S0的初始状态,因为如果S0为0,P0将仅阻塞。这是你的陈述的情况。因此,答案是P0将完全打印0 两次。
答案 3 :(得分:0)
阅读问题和代码我也会说(A)。我假设在完成任务之前不能抢占进程。
它表示初始状态为S0=1
S1=0
S2=0
,我们知道P1
和P2
只执行一次。
并发流程可能很复杂,但是我试着描述流程,人们会按照我的想法找出错误,没关系,我也在这里学习。
现在您有一些情况会产生不同的结果,具体取决于流程的顺序。
P0 -> P1 -> P0 -> P2 -> P0 = Three times
P0 -> P1 -> P2 -> P0 = Twice
P0 -> P2 -> P1 -> P0 = Twice
这给了我们至少两次的答案。
修改强>
所有这些都是在wait()阻塞的假设下进行的,而semaphore == 0并且release()设置了semaphore = 1,否则代码将主要是精神错乱。
如果流程可以随时中断,那么事情会变得有趣。
P0 starts out running because S0=1 at start
P0 print '0';
P0 release(S1);
-- here S1 may take over or not --
P0 release(S2);
-- here S2 may take over or not --
P0 goes back to wait(S0)
-- here P0 continues or if S1 *and* S2 have not run blocks --
-- it may also be that only S1 or S2 ran and now the other will run --
现在我尝试找出一种方法来想象事情会如何发挥作用,而我却找不到把它放在代码块中的方法。
如果S1和S2都尽快运行,因为信号量是二进制的,并且只能处于两种状态中的一种状态,P0只会运行两次,但是如果调度足够延迟,可以延迟S1或S2。 P0再次通过wait(),P0将运行三次。
但我认为这个问题并不意味着有可中断的过程,只会变得混乱。
答案 4 :(得分:0)
最初只有P0可以进入while循环,因为S0 = 1,S1 = 0,S2 = 0.P0首先打印' 0'然后,在释放S1和S2之后,P1或P2将执行并释放S0。所以再次打印0。