处理P0打印“0”的次数是多少?

时间:2012-08-22 08:40:14

标签: concurrency operating-system semaphore

以下程序由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)

请提前帮助谢谢

5 个答案:

答案 0 :(得分:3)

最初P0将执行,因为只有S0=1。它将打印单个0。

现在当S1S2P0发布时,其中任何一个都可以被执行。

让我们假设P1执行并释放S0(现在S0的值为1)。

现在有两种可能性P0P2可以执行。

让我们执行P2执行并释放S0,所以最后P0执行并打印0(表示两个0) 但如果P0P2之前执行,那么将打印总共3 0个(一个在P0,然后P2,这会释放S0所以{{1再次执行。)

所以完美答案至少是两个0。

答案 1 :(得分:1)

解决方法如下:

  1. 只有进程P0才能先执行。这是因为进程P0使用的信号量,即S0的初始值为1.现在当P0调用S0等待时,S0的值变为0,这意味着S0已被P0占用。就过程P1和P2而言,当它们分别在S1和S2上调用wait时,它们无法继续,因为信号量已经被初始化为取即0,所以它们必须等到S1和S2被释放!

  2. P0先行并打印0.现在接下来的陈述将释放S1和S2!当S1被释放时,过程P1的等待结束,因为S1的值上升1并且未被标记。 P1取S1并使S1成为。过程P2也是如此。

  3. 现在,only one of P1 or P2 can execute, because either of them can be in the critical section at a given time ..假设P2执行。它释放S0并终止。

  4. 让P1执行下一步.. P1开始释放S0并终止。

  5. 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的发布。

  6. 这是第二个打印0次的解决方案:

    1. P0开始,打印0和释放S1和S2。

    2. 让P2执行。 P2启动,释放S0并终止。在此之后,只能执行P0或P1。

    3. 让P0执行。第二次打印0并释放S1和S2。此时只有P1可以执行。

    4. P1开始,释放S0,P1终止。此时只有P0可以执行,因为它在一个while循环中,其条件设置为true!

    5. P0开始,第3次打印0并释放S1和S2。然后它等待有人释放从未发生过的S0。

    6. 所以答案恰好是两次或者恰好三次,也可以说是“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,我们知道P1P2只执行一次。

并发流程可能很复杂,但是我试着描述流程,人们会按照我的想法找出错误,没关系,我也在这里学习。

现在您有一些情况会产生不同的结果,具体取决于流程的顺序。

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。