先讲一讲信号量的原理吧,昨天晚上给室友讲了一下,觉得这个例子特别好,就是比如说有一个屋子10个房间里面都住着人(进程),但是只有3个厕所(资源),当然,每个人都想用厕所,并且自己用的时候不想让别人看着(这不是废话),于是,Posix就出现了,也就是信号灯,我用厕所的时候,我就先把厕所的灯(信号量的值)打开,如果有灯,则表示厕所被占用了,你一出房间门,发现亮了3盏灯,说明TMD已经没厕所了,又想上厕所,只能去等着,于是,就出现了等待队列,这时候有人用完了出来,关灯出来(V操作),看见有人等着,就把你喊过去,你进厕所,拉灯(P操作),就可以用厕所了。这个就是整个信号量操作了。
P-V操作定义:
(1)sem减1;
(2)若sem减1后仍大于或等于零,则该进程继续执行;
(3)若sem减1后小于零,则该进程被阻塞,在相应队列中排队,然后转向系统的进程调度。
V原语的主要操作是:
(1)sem加1;
(2)若相加结果大于零,则进程继续执行;
(3)若相加结果小于或等于零,则唤醒一阻塞在该信号量上的进程,然后再返回原进程继续执行或转进程调度。
典型理解偏差:
1. 以V原语的1、2步来做,Sem不就永远大于0,那进程不就一直循环执行成为死循环了?
2. Sem大于0那就表示有临界资源可供使用,为什么不唤醒进程?
3. Sem小于0应该是说没有临界资源可供使用,为什么还要唤醒进程?
4. 如果是互斥信号量的话,应该设置信号量Sen=1,但是当有5个进程都访问的话,最后在该信号量的链表里会有4个在等待,也是说S=-4,那么第一个进程执行了V操作使S加1,释放了资源,下一个应该能够执行,但唤醒的这个进程在执行P操作时因S<0 ,也还是执行不了,这是怎么回事呢?
5. Sem的绝对值表示等待的进程数,同时又表示临界资源,这到底是怎么回事?
析疑:
1. P操作对sem减1的。P、V原语必须成对使用!从而不会造成死循环。
2. Sem大于0的确表示有临界资源可供使用,而且这个时候没有进程被阻塞在这个资源上,也就是说没有进程因为得不到这类资源而阻塞,所以没有被阻塞的进程,自然不需要唤醒。
3. V原语操作的本质在于:一个进程使用完临界资源后,释放临界资源,使Sem加1,以通知其它的进程,这个时候如果Sem<0,表明有进程阻塞在该类资源上,因此要从阻塞队列里唤醒一个进程来“转手”该类资源。比如,有2个某类资源,三个进程A、B、C、D要用该类资源,最开始Sem=2,当A进入,Sem=1,当B进入Sem=0,表明该类资源刚好用完,当C进入时Sem=-1,表明有一个进程被阻塞了,D进入,Sem=-2。当A用完该类资源时,进行V操作,Sem=-1,释放该类资源,而这时Sem<0,表明有进程阻塞在该类资源上,于是唤醒一个。
4. 当一个进程阻塞了的时候,它已经执行过了P操作,并卡在临界区那个地方。当唤醒它时就立即进入它自己的临界区,并不需要执行P操作了,当执行完了临界区的程序后,就执行V操作。
http://blog.csai.cn/user1/16373/archives/2007/13360.html
关于PV操作
在计算机操作系统中,PV操作是进程管理中的难点。
首先应弄清PV操作的含义:PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下:
P(S):①将信号量S的值减1,即S=S-1;
②如果S³0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。
V(S):①将信号量S的值加1,即S=S+1;
②如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。
PV操作的意义:我们用信号量及PV操作来实现进程的同步和互斥。PV操作属于进程的低级通信。
什么是信号量?信号量(semaphore)的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程个数。注意,信号量的值仅能由PV操作来改变。
一般来说,信号量S³0时,S表示可用资源的数量。执行一次P操作意味着请求分配一个单位资源,因此S的值减