大家在学习操作系统的时候,肯定会被各种调度算法搞得焦头烂额,什么处理器调度,什么磁盘引臂调度算法,什么页面置换算法等等,但是我从一开始接触操作系统时,对这些调度算法并不感冒,反而对PV操作比较欠缺,也许是没有好好听课,又或许是没好好看书,总之再一次遭遇PV操作,我觉得不能就这么算了,得给它点color see see!
首先要搞清楚的问题是:什么是信号量?什么是PV操作?
信号量与PV操作是由荷兰著名学者E.W.Dijkstra于1965年提出来的,是最早的也是最成功的进程同步机制。这种同步机制包括一种称为信号量类型的变量以及对于此种变量所能进行的两个操作,即P(荷兰语Proberen)操作和V(荷兰语Vehogen)操作。由于荷兰语不够流行,在有些书中将P操作称为Down操作,将V操作称为Up操作。
关于信号量即P原语V原语的内部结构,就不给大家介绍了,不利于初学者理解,我们的目标是会做操作系统的PV操作题。
PV操作能够实现对临界区的管理。其具体定义如下:
P操作P(S):将信号量S减去1,若结果小于0,则把调用P(S)的进程置成等待信号量S的状态。
V操作V(S):将信号量S加1,若结果不大于0,则释放一个等待信号量S的进程。
我们规定信号量S的初值为0或者1或者其他整数,它应在系统初始化时确定。
下面给出一个PV操作的经典例子:生产者—消费者问题
begin
Buffer:integer;
SP,SG:semaphore;
SP:=1;SG:=0;
Cobegin
Processproducer
Begin
L1:producea product;
P(SP);
Buffer:=product;
V(SG);
Go to L1
End;
Processconsumer
Begin
L2:P(SG);
Take a product;
V(SP);
Consume;
Go to L2
End;
Coend;
End;
对于Buffer我们可以理解为一个容器,用来存放生产者生产的产品,并且一次只能放一个,那么信号量SP就表示容器中是否有产品,初值为1代表容器为空,可以放1个产品,而信号量SG表示容器中产品的个数,初值为0代表容器中没有产品。
对于生产者来说,生产一个产品后调用P(SP)来查看容器是否为空,如果为空则把产品放进去,否则将信号量减1,将进程置为等待状态,当放进去一个产品后,生产者要调用V(SG)来通知消费者,告知消费者容器中有1个产品,可以去取出来了,然后消费者调用P(SG)判断容器中是否有产品,如果有则取出来,否则将信号量减1,并且等待,当消费者把产品取出来之后,要调用V(SP)来通知生产者,容器已经空了,可以将生产出来的产品放进去了,然后就是循环了,如此往复,两个进程就可以同步执行了。