进程同步(1)之PV操作/信号量/互斥量

  OS,信号量表示资源实体数,早期信号量只是一个Int,单纯从一个int的确可以表示出资源数,但是当有多个进程抢占CPU,下一次的抢占将会造成进程队列的混乱.例如:ABCD 4个进程, A先抢到了CPU,在下一次进行CPU抢占时,将会导致BCD的次序是不可预知的.所以引进了一个信号量的数据结构semaphore.

PV

  PV操作是由荷兰人Dijkstra提出的(荷兰语中,P:Proberen是检测的意思,V:Verhogen是增量的意思).PV操作可以解决并发进程间CPU的竞争,又能解决并发进程的协作关系.PV操作是遵循的公平策略是FCFS.

注意:PV操作是一段原语操作.学过数据库,我们都知道原语是指一段代码,要么全做,要么不做,这段代码未完成是不可中断的.

看以下一段代码

 

 1 typedef struct semaphore{

 2 

 3   int value; //信号量值

 4 

 5   struct pcb *list;//信号量队列指针

 6 

 7 };

 8 

 9 //进行P测试(无资源则挂起)

10 

11 void P(semaphore &s){

12 

13   s.value--;

14 

15   if(s.value<0){//判断是否还有资源,没有资源则休眠,有资源则通过P测试

16 

17     W.(s.list);//进程休眠操作wait.

18 

19   }

20 

21 }

22 

23 //进行V操作(队列有休眠进程则唤醒唤醒)

24 

25 void V(semaphore &s){

26 

27   s.value++;

28 

29   if(s.value<=0){//判断是否有进程在等待,有的话则唤醒进程

30 

31     R(s.list);// 释放进程 release.

32 

33   }

34 

35 }

 

  这段就是PV操作的核心代码.

  P操作中,如果没有资源则会阻塞自己(调用P操作的进程),并将自己放入等待调度的队列.

  V操作中,如果有被阻塞的队列则唤醒进程.

Note:

value初始值为资源数.

value等于0, 资源刚好用完,

value大于0, 还有资源.

value小于0, 绝对值等于挂起队列中的进程数.

互斥量

  互斥量从字面很容易理解,就是解决进程间的互斥关系.

  一般互斥量用在并发进程进入临界区前的测试.(临界区:并发进程中与共享变量有关的代码段)

实现代码如下:

 1 semaphore mutex;

 2 

 3 mutex = 1;

 4 

 5 void M(){

 6 

 7   P(mutex);

 8 

 9   {临界区}

10 

11   V(mutex);

12 

13 }

Note:

  mutex取值为1/0,mutex等于1时表示临界区可用.mutex等于0表示临界区不可用.mutex也可以对共享资源加锁.

概念总结:

1)同步:信号量初始化S0=n,S1=0,两个并发进程需要两个信号量,后做的进程初始化为0,另一个进程初始化值为资源数.当引入更多并发进程时,每增加一个进程则相应增加一个信号量.

2)互斥:信号量有且只有一个,初始值为1.

你可能感兴趣的:(信号量)