问题:
总共有 读入、执行、打印 三个进程,试用PV操作描述读入B1打印B2的同步过程。
问题解读:
这个问题就是说了这样一件事:一个输入B1,被操作之后,成为B2,将B2打印。怎样用PV操作来说这件事。那么新的问题来了:啥是个PV操作?
就拿这道题来解释PV操作吧,我想打印一个值,前提条件是这个值存在吧,如果不存在,那么打印这个动作就不应该被执行,不能说啥也没有在那瞎打印吧。那么怎样才能让它不执行呢?
这就需要引入信号量机制了:
- 当一个操作的信号量为负数的话,就会挂起等待,不执行。
- 当一个操作的信号量为0或者正数的时候,就可以执行。
- P操作会使信号量 -1,V操作会使信号量 +1。
解决问题:
按理说,我有三个操作,读入(Reader)、执行(Executer)、打印(Printer),应该对应设置三个信号量R、E、P,对应PV操作流程如下图所示:
解释上图的步骤:
首先,将输入信号量R初始化为1,保证读入进程Reader能够启动。
如果这时候没有从Reader进程开始执行,而是试图执行Executer或者Printer进程,由于信号量E、P初始值都是0,而且一上来就是P操作,所以会使信号量E、P成为 -1,这样进程将会挂起等待,不执行。
所以,能执行的进程只有读入进程Reader。
接着看,执行P(R),会使信号量R-1得0,执行输入B1操作,这时候B1已经被输入了,继续执行V(E)操作来唤醒Executer进程,再往下就是执行V(R)操作来再次唤醒读入进程。这就有Bug了,因为刚刚输入的B1还不一定被Executer进程处理了呢,就唤醒了下次的读入,这就有可能出现第二次的读入内容将第一次的读入内容覆盖,导致结果错误。
为了避免这样的Bug发生,我们需要引入第四个信号量N,即Next输入信号量,并且初始化为0。
现在总共就有四个信号量了,分别是输入信号量R=1,Next输入信号量N=0,B1存在信号量E=0,B2存在信号量P=0,对应PV操作流程如下图所示:
解释上图的步骤:
在三个信号量的基础之上,加入了Next输入信号量N,并初始化为0。
当Reader进程执行到P(N)的时候,由于N的初始信号量为0,对N进行一次P操作,N-1 = -1,Reader进程将被挂起等待,无法继续执行。等到Executer进程执行完输出B2的时候,下一步执行V(N),对N进行一次V操作,N+1 = 0,Reader进程将被唤醒。这样,在将B1执行的结果B2输出之后,才允许第二次输入,可以避免因第二次输入覆盖第一次输入而导致结果错误的Bug。
这里我再给出老师课堂上给出的答案,我个人认为两个版本的差别不是很大,所以这个就不再一步一步解释了:
结尾:
在课堂上我给出了我的解法思路,结果一下课问同学们理解不理解我的思路?结果是问一个一个不懂,很是郁闷。遂作此文。其实我觉得我那个版本还存在问题,但是由于是自己想出来的,思维定式,一时半会找不出来,希望看懂的同学给指点指点,定当感激。
操作系统老师课堂语录收集:
1、师父领进门,修行靠个人。
2、学生的主业就是上课,所以你们没事就都来上课啊。
3、编故事也是一种能力,描述能力。
4、非我族类,其心必异。
5、要想有秩序,必须有规则。
6、千万不要等着,掌握了70%就上,做着做着就到90%了。
7、有时候方法简单一点,你就会忽略这实际上是一种方法;有时候方法复杂一点,多想几步,这个方法就上升成为一种策略了。
8、我那时候的操作系统老师对我们讲:操作系统这门课你们现在学是学不懂的,等毕业你就懂了。
9、一等人才制定游戏规则,二等人才执行游戏规则,三等人才玩游戏。
10、要想有说服力,需要用量化。
未完待续......
原文地址:https://www.cnblogs.com/littlecurl/p/PVoperation.html