P操作和V操作是不可中断的程序段,称为原语,PV原语及信号量的概念都是由荷兰科学家E.W.Dijkstra提出的。
信号量sem是一个整数,Sem大于等于零时代表可供并发进程使用的资源实体数,sem小于零时则表示正在等待申请资源的进程数。
P原语操作
(1) sem减 1 ;
(2) 若sem大于等于0,则请求的进程继续执行;
(3) 若sem小于0,则进程被阻塞后进入与该信号相对应的等待队列中,然后转进程调度。
V原语操作
(1) sem加 1 ;
(2) 若sem大于0,则请求的进程继续执行;
(3) 若sem小于等于0,则从该信号的等待队列中唤醒一个等待进程,然后再返回原进程继续执行或转进程调度。
注意事项:
⑴每个程序中用户实现互斥的P、V操作必须成对出现,先做P操作,进临界区,后做V操作,出临界区。若有多个分支,要认真检查其成对性。
⑵P、V操作应分别紧靠临界区的头尾部,临界区的代码应尽可能短,不能有死循环。
⑶互斥信号量的初值一般为1。
典型问题:
1、V操作中 ,Sem大于0那就表示有可供使用,为什么不唤醒进程?
==》Sem大于0的确表示有临界资源可供使用,而且这个时候没有进程被阻塞在这个资源上,也就是说没有进程因为得不到这类资源而阻塞,所以没有被阻塞的进程,自然不需要唤醒。
2、V操作中 ,Sem小于等于0应该是说没有临界资源可供使用,为什么还要唤醒进程?
==》V原语操作的本质在于:一个进程使用完临界资源后,释放临界资源,使Sem加1,以通知其它的进程。这个时候如果Sem<=0,表明有进程阻塞在该类资源上,因此要从等待队列里唤醒一个进程来“转手”该类资源。
比如,有两个某类资源,四个进程A、B、C、D要用该类资源,最开始Sem=2,当A进入,Sem=1;当B进入Sem=0,表明该类资源刚好用完;当C进入时Sem=-1,表明有一个进程被阻塞了;D进入,Sem=-2。当A用完该类资源时,进行V操作,Sem=-1,释放该类资源,而这时Sem<=0,表明有进程阻塞在该类资源上,于是唤醒一个。
3、Sem的绝对值表示等待的进程数,同时又表示临界资源,这到底是怎么回事?
==》当信号量Sem小于0时,其绝对值表示因请求该类资源而被阻塞的进程数目。S大于0时表示可用的临界资源数。注意在不同情况下所表达的含义不一样。当S等于0时,表示临界资源刚好用完。
4、如果是互斥的话,应该设置信号量Sem=1,但是当有5个进程都访问的话,最后在该信号量的链表里会有4个在等待,也是说S=-4,那么第一个进程执行了V操作使S加1,释放了资源,下一个应该能够执行,但唤醒的这个进程在执行P操作时因S<0,也还是执行不了,这是怎么回事呢?
==》当一个进程阻塞了的时候,它已经执行过了P操作,并卡在那个地方。当唤醒它时就立即进入它自己的临界区,并不需要执行P操作了,当执行完了临界区的程序后,就执行V操作。
参考自:PV操作原理概述-dyli2000-ChinaUnix博客