进程同步(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.

原文地址:https://www.cnblogs.com/localhost/p/2447067.html