`

用信号量机制来实现多个进程对临界资源的互斥访问 & PV操作

阅读更多
进程互斥  定义:两个或两个以上的进程,不能同时进入关于同一组共享变量的临界区域,否则可能发生与时间有关的错误,这种现象被称作进程互斥.
  在多道程序环境下,存在着临界资源,它是指多进程存在时必须互斥访问的资源。也就是某一时刻不允许多个进程同时访问,只能单个进程的访问。我们把这些程序的片段称作临界区或临界段,它存在的目的是有效的防止竞争条件又能保证最大化使用共享数据。而这些并发进程必须有好的解决方案,才能防止出现以下情况:多个进程同时处于临界区,临界区外的进程阻塞其他的进程,有些进程在临界区外无休止的等待。除此以外,这些方案还不能对CPU的速度和数目做出任何的假设。只有满足了这些条件,才是一个好的解决方案。
  访问临界资源的循环进程可以这样来描述:
  Repeat
  entry section
  Critical sections;
  exit section
  Remainder sectioni;
  Until false
  为实现进程互斥,可以利用软件的方法,也可以在系统中设置专门的同步机制来协调多个进程,但是所有的同步机制应该遵循四大准则:
  1.空闲让进 当临界资源处于空闲状态,允许一个请求进入临界区的进程立即进入临界区,从 而有效的利用资源。
  2.忙则等待 已经有进程进入临界区时,意味着相应的临界资源正在被访问,所以其他准备进 入临界区的进程必须等待,来保证多进程互斥。
  3.有限等待 对要求访问临界资源的进程,应该保证该进程能在有效的时间内进入临界区,防 止死等状态。
  4.让权等待 当进程不能进入临界区,应该立即释放处理机,防止进程忙等待。
  早期解决进程互斥问题有软件的方法和硬件的方法,如:严格轮换法,Peterson的解决方案,TSL指令,Swap指令都可以实现进程的互斥,不过它们都有一定的缺陷,这里就不一一详细说明,而后来Kijkstra提出的信号量机制则更好的解决了互斥问题。


信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。
  Semaphore分为单值和多值两种,前者只能被一个线程获得,后者可以被若干个线程获得。
  以一个停车场的运作为例。简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如 果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车 场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。
  在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用。
  抽象的来讲,信号量的特性如下:信号量是一个非负整数(车位数),所有通过它的线程/进程(车 辆)都会将该整数减一(通过它当然是为了使用资源),当该整数值为零时,所有试图通过它的线程都将处于等待状态。在信号量上我们定义两种操作: Wait(等待) 和 Release(释放)。当一个线程调用Wait操作时,它要么得到资源然后将信号量减一,要么一直等下去(指放入阻塞队列),直到信号量大于等于一时。 Release(释放)实际上是在信号量上执行加操作,对应于车辆离开停车场,该操作之所以叫做“释放”是因为释放了由信号量守护的资源。
  信号量,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必 须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过 程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量。
  
信号量的分类:

  
  整型信号量(integer semaphore):信号量是整数
  记录型信号量(record semaphore):每个信号量s除一个整数值s.value(计数)外,还有一个进程等待队列s.L,其中是阻塞在该信号量的各个进程的标识
  二进制信号量(binary semaphore):只允许信号量取0或1值
  每个信号量至少须记录两个信息:信号量的值和等待该信号量的进程队列。它的类型定义如下:(用类PASCAL语言表述)
  semaphore = record
  value: integer;
  queue: ^PCB;
  end;
  其中PCB是进程控制块,是操作系统为每个进程建立的数据结构。
  s.value>=0时,s.queue为空;
  s.value<0时,s.value的绝对值为s.queue中等待进程的个数;
  信号量的创建

  同共享内存一样,系统中同样需要为信号量集定制一系列专有的操作函数(semget,semctl等)。系统命令ipcs可查看当前的系统IPC的状态,在命令后使用-s参数。使用函数semget可以创建或者获得一个信号量集ID,函数原型如下:
  #include <sys/shm.h>
  int semget( key_t key, int nsems, int flag);
  函数中参数key用来变换成一个标识符,每一个IPC对象与一个key相对应。当新建一个共享内存段时,使用参数flag的相应权限位对ipc_perm结构中的mode域赋值,对相应信号量集的shmid_ds初始化的值如表1所示。
  表1shmid_ds结构初始化值表
  
ipc_perm结构数据
   初 值
   ipc_perm结构数据
   初 值
  
Sem_otime
   0
   Sem_nsems
   Nsems
  
Sem_ctime
   系统当前值
   参数nsems是一个大于等于0的值,用于指明该信号量集中可用资源数(在创建一个信号量 时)。当打开一个已存在的信号量集时该参数值为0。函数执行成功,则返回信号量集的标识符(一个大于等于0的整数),失败,则返回–1。函数semop用 以操作一个信号量集,函数原型如下: #include <sys/sem.h>
  int semop( int semid, struct sembuf semoparray[], size_t nops );
  函数中参数semid是一个通过semget函数返回的一个信号量标识符,参数nops标明了 参数semoparray所指向数组中的元素个数。参数semoparray是一个struct sembuf结构类型的数组指针,结构sembuf来说明所要执行的操作




关 于 PV 操 作
http://blog.csdn.net/leves1989/archive/2008/11/15/3305609.aspx


在计算机操作系统中,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的值减1;当S<0时,表示已经没有可用资源,请求者必须等待别的进程释放该类资源,它才能运行下去。而执行一个V操作意味着释放一个单位资源,因此S的值加1;若S£0,表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。
    利用信号量和PV操作实现进程互斥的一般模型是:
进程P1              进程P2           ……          进程Pn
……                  ……                           ……
P(S);              P(S);                         P(S);
临界区;             临界区;                        临界区;
V(S);              V(S);                        V(S);
……                  ……            ……           ……
    其中信号量S用于互斥,初值为1。
    使用PV操作实现进程互斥时应该注意的是:
    (1)每个程序中用户实现互斥的P、V操作必须成对出现,先做P操作,进临界区,后做V操作,出临界区。若有多个分支,要认真检查其成对性。
    (2)P、V操作应分别紧靠临界区的头尾部,临界区的代码应尽可能短,不能有死循环。
   (3)互斥信号量的初值一般为1。
    利用信号量和PV操作实现进程同步
PV操作是典型的同步机制之一。用一个信号量与一个消息联系起来,当信号量的值为0时,表示期望的消息尚未产生;当信号量的值非0时,表示期望的消息已经存在。用PV操作实现进程同步时,调用P操作测试消息是否到达,调用V操作发送消息。
    使用PV操作实现进程同步时应该注意的是:
    (1)分析进程间的制约关系,确定信号量种类。在保持进程间有正确的同步关系情况下,哪个进程先执行,哪些进程后执行,彼此间通过什么资源(信号量)进行协调,从而明确要设置哪些信号量。
    (2)信号量的初值与相应资源的数量有关,也与P、V操作在程序代码中出现的位置有关。
    (3)同一信号量的P、V操作要成对出现,但它们分别在不同的进程代码中。
【例1】生产者-消费者问题
在多道程序环境下,进程同步是一个十分重要又令人感兴趣的问题,而生产者-消费者问题是其中一个有代表性的进程同步问题。下面我们给出了各种情况下的生产者-消费者问题,深入地分析和透彻地理解这个例子,对于全面解决操作系统内的同步、互斥问题将有很大帮助。
(1)一个生产者,一个消费者,公用一个缓冲区。
定义两个同步信号量:
empty——表示缓冲区是否为空,初值为1。
   full——表示缓冲区中是否为满,初值为0。
生产者进程
while(TRUE){
生产一个产品;
     P(empty);
     产品送往Buffer;
     V(full);
}
消费者进程
while(True){
P(full);
   从Buffer取出一个产品;
   V(empty);
   消费该产品;
   }
(2)一个生产者,一个消费者,公用n个环形缓冲区。
定义两个同步信号量:
empty——表示缓冲区是否为空,初值为n。
full——表示缓冲区中是否为满,初值为0。
    设缓冲区的编号为1~n-1,定义两个指针in和out,分别是生产者进程和消费者进程使用的指
,指向下一个可用的缓冲区。
生产者进程
while(TRUE){
     生产一个产品;
     P(empty);
     产品送往buffer(in);
     in=(in+1)mod n;
     V(full);
}

消费者进程
while(TRUE){
P(full);
   从buffer(out)中取出产品;
   out=(out+1)mod n;
   V(empty);
   消费该产品;
   }
(3)一组生产者,一组消费者,公用n个环形缓冲区
    在这个问题中,不仅生产者与消费者之间要同步,而且各个生产者之间、各个消费者之间还必须互斥地访问缓冲区。
定义四个信号量:
empty——表示缓冲区是否为空,初值为n。
full——表示缓冲区中是否为满,初值为0。
mutex1——生产者之间的互斥信号量,初值为1。
mutex2——消费者之间的互斥信号量,初值为1。

    设缓冲区的编号为1~n-1,定义两个指针in和out,分别是生产者进程和消费者进程使用的指针,指向下一个可用的缓冲区。
生产者进程
while(TRUE){
     生产一个产品;
     P(empty);
     P(mutex1);
     产品送往buffer(in);
     in=(in+1)mod n;
     V(mutex1);
     V(full);
}
消费者进程
while(TRUE){
P(full)
   P(mutex2);
   从buffer(out)中取出产品;
   out=(out+1)mod n;
   V(mutex2);
   V(empty);
   消费该产品;
   }
  需要注意的是无论在生产者进程中还是在消费者进程中,两个P操作的次序不能颠倒。应先执行同步信号量的P操作,然后再执行互斥信号量的P操作,否则可能造成进程死锁。
【例2】桌上有一空盘,允许存放一只水果。爸爸可向盘中放苹果,也可向盘中放桔子,儿子专等吃盘中的桔子,女儿专等吃盘中的苹果。规定当盘空时一次只能放一只水果供吃者取用,请用P、V原语实现爸爸、儿子、女儿三个并发进程的同步。

分析 在本题中,爸爸、儿子、女儿共用一个盘子,盘中一次只能放一个水果。当盘子为空时,爸爸可将一个水果放入果盘中。若放入果盘中的是桔子,则允许儿子吃,女儿必须等待;若放入果盘中的是苹果,则允许女儿吃,儿子必须等待。本题实际上是生产者-消费者问题的一种变形。这里,生产者放入缓冲区的产品有两类,消费者也有两类,每类消费者只消费其中固定的一类产品。

    解:在本题中,应设置三个信号量S、So、Sa,信号量S表示盘子是否为空,其初值为l;信号量So表示盘中是否有桔子,其初值为0;信号量Sa表示盘中是否有苹果,其初值为0。同步描述如下:
int S=1;
int Sa=0;
int So=0;
      main()
      {
        cobegin
            father();      /*父亲进程*/
            son();        /*儿子进程*/
            daughter();    /*女儿进程*/
        coend
    }
    father()
    {
        while(1)
          {
            P(S);
            将水果放入盘中;
            if(放入的是桔子)V(So);
            else  V(Sa);
           }
     }
    son()
    {
        while(1)
          {
             P(So);
             从盘中取出桔子;
             V(S);
             吃桔子;
            }
    }
    daughter()
    {
         while(1)
            {
              P(Sa);
              从盘中取出苹果;
              V(S);
              吃苹果;
            }


思考题:

四个进程A、B、C、D都要读一个共享文件F,系统允许多个进程同时读文件F。但限制是进程A和进程C不能同时读文件F,进程B和进程D也不能同时读文件F。为了使这四个进程并发执行时能按系统要求使用文件,现用PV操作进行管理,请回答下面的问题:
    (1)应定义的信号量及初值:                    。
    (2)在下列的程序中填上适当的P、V操作,以保证它们能正确并发工作:
     A()                B()                  C()                 D()
      {                 {                    {                  {
      [1];                [3];                  [5];                 [7];
      read F;             read F;                read F;              read F;
     [2];                [4];                  [6];                 [8];
      }                  }                    }                  }
    思考题解答:
(1)定义二个信号量S1、S2,初值均为1,即:S1=1,S2=1。其中进程A和C使用信号量S1,进程B和D使用信号量S2。
(2)从[1]到[8]分别为:P(S1) V(S1) P(S2) V(S2) P(S1) V(S1) P(S2) V(S2)
分享到:
评论

相关推荐

    PV操作论文(进程的同步与互斥)

    为了解决这个问题,Dijkstra提出了信号量机制,通过P(测试并操作)和V(增值操作)两个原语来实现对临界区的管理。 P操作原语用于请求资源,它会尝试减少信号量的值,如果资源可用(信号量大于0),则进程继续执行...

    利用P、V操作实现进程同步与互斥

    进程互斥的实现部分详细讲解了通过P、V操作来保证进程对临界资源的互斥访问。进程互斥要求在任一时刻只有一个进程可以访问临界资源,以避免竞争条件导致的资源冲突。实现互斥的方法是在临界区代码前后加上P、V操作,...

    信号量机制(pv操作)1

    【信号量机制(PV操作)】是操作系统中用于进程同步和互斥的一种机制。它通过两个原子操作,P(wait)操作和V(signal)操作,来管理对公共资源的访问。P操作代表“减”,V操作代表“加”,在信号量上执行,以控制...

    C语言实现pv操作演示程序

    PV操作常用于解决临界区问题,即多个进程需要访问同一段共享资源,但为了防止数据不一致,必须确保一次只有一个进程可以进入临界区。PV操作通过协调进程对共享资源的访问,实现同步和互斥。 在"C语言实现pv操作演示...

    信号量与PV操作,操作系统信号量与PV操作

    进程在使用资源之前要在相应的信号量上做P操作,使用完要在相应信号量上做V操作,进程之间通过信号量和PV操作实现同步。 3.3.4 用信号量解决生产者-消费者问题 信号量可以用来解决生产者-消费者问题。例如,使用两...

    进程同步——信号量机制

    关于信号量的文章,生产者消费者问题与读者写者问题---信号量机制,PV操作——进程同步的信号量问题,利用信号机制实现的 父子进程同步,嵌入式linux的学习笔记-进程间通信的信号与信号集(四)1)进程的同步与互斥 ...

    PV操作的实现(源代码+报告)

    在操作系统中,PV操作(P操作和V操作)用于管理共享资源,确保多个进程能正确、有序地访问这些资源,防止数据竞争和其他并发问题。下面将详细介绍PV操作的原理、实现方式以及其在实际应用中的作用。 1. PV操作的...

    进程PV操作详细讲解

    在多个进程需要访问同一资源的情况下,可以通过设置信号量来确保资源在同一时间仅被一个进程使用。例如,考虑两个进程A和B,它们都需要访问一个公共资源——箱子,为了保证互斥访问,可以设置信号量`s`的初始值为1...

    第六章 进程间互斥、同步与通信(操作系统原理).pptx

    6. 信号量:信号量是一个计数器,可以用来控制对临界资源的访问。当信号量为0时,表示资源已被占用,等待的进程会被阻塞;否则,进程可以获取资源并减少信号量。 7. 管程:一种高级的同步原语,包含临界区和控制...

    进程同步典型例题(操作系统)

    信号量可以实现对临界区的互斥访问,也可以实现进程间的同步。当信号量用于互斥时,初始值一般为1;而用于同步时,初始值则根据需要的同步次数设置。 2. 信号量的P操作与V操作 P操作(wait或proberen),通常执行...

    3.3 信号量与PV操作.pptx

    1. **利用信号量实现互斥**:通过设置一个初始值为1的信号量,可以确保任何时刻只有一个进程能够访问某个资源或执行某个临界区代码段。这种方式主要用于实现进程间的互斥。 2. **利用信号量实现进程同步**:当多个...

    操作系统课程设计PV操作

    首先,PV操作源于信号量(Semaphore)概念,信号量是一个整型变量,用于控制对共享资源的访问。信号量分为两种类型:互斥信号量和共享信号量。互斥信号量用于保护临界区,保证同一时刻只有一个进程可以访问;共享...

    全面深入的学习进程间通信机制之一:信号量

    **信号量**是一种用于管理进程间对共享资源访问的重要机制,尤其在操作系统中扮演着核心角色。它能够确保资源的一致性和完整性,避免了并发访问所带来的问题。 #### 二、临界资源与临界代码 - **临界资源**指的是...

    操作系统第三章进程同步与通信.ppt

    在操作系统中,我们使用信号量和 PV 操作来实现进程同步。信号量是一个数据结构,包括一个整型值和一个等待队列。信号量只能通过 P 原语和 V 原语访问。 P 原语的作用是申请临界资源,如果该资源正被其他进程使用,...

    3.1 并发进程的同步、互斥与死锁(1).1 并发进程的同步、互斥与死锁.pptx

    为了确保临界区的安全访问,必须采用适当的机制来实现对临界区的保护。常见的机制包括: - **信号量**:通过信号量的PV操作来控制对临界区的访问。 - **管程**:提供了一种更为高级的临界区保护机制,它不仅限于简单...

    操作系统PV操作大全

    首先,PV操作源于信号量(Semaphore)的概念,信号量是一个整型变量,用于控制对共享资源的访问。信号量分为两种类型:互斥信号量和同步信号量。互斥信号量用来保护临界区,保证同一时刻只有一个进程访问;同步信号...

    pv操作经典例题,冲刺突击例题

    PV 操作的意义在于使用信号量及 PV 操作来实现进程的同步和互斥,从而解决进程之间的通信和竞争问题。 PV 操作的定义: P(S):①将信号量 S 的值减 1,即 S=S−1;②如果 S≥0,则该进程继续执行;否则该进程置...

    PV操作专讲.pdf

    ### PV操作专讲知识点概述 ...通过使用信号量和P、V操作,可以有效地解决进程间的同步和互斥问题,从而保证多道程序系统中的程序执行的有序性和确定性。了解并掌握这些基础知识对于学习操作系统和并发编程至关重要。

    进程同步的几种机制

    信号量是一种常用的同步工具,通过信号量及其PV操作来实现进程的同步和互斥。 #### PV操作 PV操作由P操作和V操作组成,它们都是不可中断的操作。P操作用于请求资源,V操作用于释放资源。 - **P(S)** 操作:将信号...

Global site tag (gtag.js) - Google Analytics