1

在某个系统中,三个线程的执行是使用三个信号量S1、S2和S3同步的,如下图所示。信号量 S1 和 S2 被初始化为零,而信号量 S3 被初始化为 1。所有三个信号量仅在下面显示的代码部分中使用。

Thread A   Thread B  Thread C
...        ...       ...
P(S1)      P(S2)     P(S3)
P(S1)      P(S1)     V(S1)
x=3*x+4    x=x+7     x=x*5
V(S2)      V(S2)     V(S1)
V(S1)      V(S1)     V(S3)

…………

如果变量 x 被定义为一个整数共享变量,初始化为 1,并且在代码的任何其他部分(除了上面显示的部分)没有赋值,那么当所有线程完成执行时,它的值是多少?三个信号量的值是多少?

我正在尝试解决这篇过去的论文,以便为我的操作系统考试做准备。我不明白如何修改变量 x 以及三个信号量如何协同工作。如果有人可以逐步向我展示信号量如何协同工作以及如何修改变量,我将不胜感激。

如果您有任何其他类似的示例可以练习,请不要犹豫链接它。

4

1 回答 1

1

让我们来看看这个过程。

请在开始之前阅读维基百科文章:信号量编程:语义和实现部分。它将解释 P() 和 V() 运算符的作用。

初始:S1=0,S2=0,S3=1

  1. 线程 A 递减 S1,线程 B 递减 S2。S1=-1,S2=-1。因为这些值为负数,所以这两个线程都会阻塞。

    状态:S1=-1,S2=-1,S3=0,线程 A 在 S1 上阻塞(指令 1),线程 B 在 S2 上阻塞(指令 1),线程 C 未阻塞(指令 1),x = 1

  2. 线程 C 递减现在为 0 的 S3。因为这不是负数,所以该线程不会阻塞。线程 C 现在递增 S1。线程 1 在 S1 上阻塞,立即解除阻塞并重新递减 S1,导致它再次阻塞。

    状态:S1=-1,S2=-1,S3=0,线程 A 在 S1 上阻塞(指令 2),线程 B 在 S2 上阻塞(指令 1),线程 C 未阻塞(指令 3),x = 1

  3. 线程 C 执行x=x*5,将 x 从 1 更改为 5。线程 C 然后递增 S1。线程 1,在 S1 上阻塞,立即解除阻塞。然后线程 C 再次增加 S3 并结束。

    状态:S1=0,S2=-1,S3=1,线程 A 未阻塞(指令 3),线程 B 在 S2 上阻塞(指令 1),线程 C 完成,x = 5

  4. 线程 A 执行x=3*x+4,将 x 从 5 更改为 19。线程 A 然后递增 S2。在 S2 上阻塞的线程 B 立即解除阻塞。然后线程 A 再次增加 S1 并结束。

    状态:S1=1,S2=0,S3=1,线程 A 完成,线程 B 未阻塞(指令 2),线程 C 完成,x = 19

  5. 线程 B 递减 S1,现在为零。因为这不是负数,所以它继续执行x=x+7,将 x 从 19 更改为 26。线程 B 然后递增 S2,然后递增 S1 并结束。

    最终状态:S1=1、S2=1、S3=1

现在让我们通过计算每个信号量的 P() 和 V() 调用来仔细检查我们的结果,并确保我们没有遗漏任何东西。由于没有循环,我们可以轻松地做到这一点,因为所有三个线程中的每条指令都只执行一次。

  • S1 的初始值为 0。三个 P(S1) 调用将其递减为 -3。四个 V(S1) 调用将其增加到 1。我们的结果显示最终 S1 = 1。 检查
  • S2 的初始值为 0。一个 P(S2) 调用将该值递减为 -1。两次 V(S2) 调用将其增加到 1。我们的结果显示最终 S2 = 1。 检查
  • S3 的初始值为 1。一个 P(S3) 调用将该值减为 0。一个 V(S3) 调用将该值增加到 1。我们的结果显示最终 S3 = 1。 检查

祝你考试顺利!

于 2014-01-08T20:41:09.093 回答