PV操作

1信号量

信号量是一种实现进程同步与互斥的工具,分为整形信号量与记录型信号量

1.1整形信号量

定义为一个用于表示资源个数的整形量S

1.2记录型信号量

含有一个整形变量和一个等待队列

typedef struct Semaphore{

int value;

L:等待队列;

}

value表示资源个数,value>0表示可用资源个数,value<0表示请求该资源被阻塞的进程个数,即在该信号量的等待队列L上排队的进程个数

2信号量操作

2.1P操作

申请一个资源

S.value=S.value-1;

if S.value>=0  该类资源没有用完,进程继续执行

if S.value<0  该类资源已经分配完毕,阻塞该进程并将其插入等待队列L中

2.2V操作

释放一个资源

S.value=S.value+1;

if S.value>0 进程继续执行

if S.value<=0  从等待队列L中唤醒第一个进程,然后再返回原进程继续执行或转进程调度

TIPs:

Sem大于0那就表示有临界资源可供使用,为什么不唤醒进程?

Sem大于0的确表示有临界资源可供使用,而且这个时候没有进程被阻塞在这个资源上,也就是说没有进程因为得不到这类资源而阻塞,所以没有被阻塞的进程,自然不需要唤醒


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,表明有进程阻塞在该类资源上,于是唤醒一个


如果是互斥信号量的话,应该设置信号量Sem=1,但是当有5个进程都访问的话,最后在该信号量的链表里会有4个在等待,也是说S=-4,那么第一个进程执行了V操作使S加1,释放了资源,下一个应该能够执行,但唤醒的这个进程在执行P操作时因S〈0,也还是执行不了,这是怎么回事呢?

当一个进程阻塞了的时候,它已经执行过了P操作,并卡在临界区那个地方。当唤醒它时就立即进入它自己的临界区,并不需要执行P操作了,当执行完了临界区的程序后,就执行V操作。


每个程序中用户实现互斥的P、V操作必须成对出现,先做P操作,进临界区,后做V操作,出临界区。若有多个分支,要认真检查其成对性。信号量的初值与相应资源的数量有关。

你可能感兴趣的:(信号量,PV操作)