zoukankan      html  css  js  c++  java
  • 信号量与管程

    一、概述

     信号量是操作系统提供的一种协调共享资源访问的方法。和用软件实现的同步比较,软件同步是平等线程间的的一种同步协商机制,不能保证原子性。而信号量则由操作系统进行管理,地位高于进程,操作系统保证信号量的原子性。

       信号量是跟锁机制在同一个层次上的编程方法。

       管程是为了解决信号量在临界区的PV操作上的配对的麻烦,把配对的PV操作集中在一起,生成的一种并发编程方法。其中使用了条件变量这种同步机制。

        

    二、信号量

      1)概述

      信号中包括一个整形变量,和两个原子操作P和V,其原子性由操作系统保证,这个整形变量只能通过P操作和V操作改变。

        P意味着信号量值减1,减完之后如果信号量值小于0,则说明资源不够用的,把进程加入等待队列。

      V意味着信号量值加1,加完之后如果信号量值小于等于0,则说明等待队列里有进程,那么唤醒一个等待进程。

        

        

      信号量的等待进程被放在等待队列中,按先进先出的次序执行。

        自旋锁不能保证进程按先进先出的次序执行,因为自旋锁的所有等待进程都在循环中忙等待,在临界区释放的那一刻,先检查到临界区为空的进程先进入临界区,没有先来后到之分。

      2)具体实现:

       

      3)信号量分类:

        i)二进制信号量:资源数目为0或1

        ii)资源信号量:资源数目为任何非负值

        两者其实是等价的,基于一个可以实现另一个。

      4) 信号量作用:

       i)实现临界区的互斥访问

         进入临界区之前使用P操作,如果信号量为1,则进入,且信号量设置为0。如果信号量为0,则进入等待队列。

         退出临界区之后使用V操作,信号量值加1,如果信号量还小于等于0,则唤醒等待队列中的一个进程。

         

      ii)实现条件同步

        一个线程A使用P操作,一个线程B使用V操作,初始的信号量设置为0。则为了满足某个条件,必须在线程B执行之后,才可以执行线程A。用信号量可以轻松实现这一点。

     

     5)用信号量实现生产者-消费者问题

      

         

        

     6)使用信号量的缺陷

        读/开发代码比较困难,而且PV在不同的线程里配对,容易写错。而且必须先检查资源信号量的值,再进入临界区(即先写emptyBuffers->P(),再写mutex->P()),否则所有线程都不能进入临界区。

    三、管程

     1)概述

       管程是为了解决信号量在临界区的PV操作上的配对的麻烦,把配对的PV操作集中在一起,生成的一种并发编程方法。其中使用了条件变量这种同步机制。

       管程与临界区不同的是,在管程中的线程可以临时放弃管程的互斥访问,让其他线程进入到管程中来。而临界区中的线程只能在线程退出临界区时,才可以放弃对临界区的访问。

        

      2)管程的组成

        当条件变量的数目为0时,管程和临界区相同。

        

      3)条件变量

      一个条件变量就对应于一个等待队列,每个条件变量有一个Wait()操作和Signal()操作。

        

       

     4)用管程实现生产者-消费者问题

       

     先进入管程,再进行判断。就是因为管程中的线程可以放弃对管程的互斥访问,交由其他线程访问管程。

       (视频里说 管程可以把PV操作都集中到一个模块里,我对此有疑问。。在我看来,不就是把两个信号量表示成两个条件变量了嘛。。PV还是分散的啊。求指教)

      5)管程条件变量的释放处理方式

        进程A执行,被阻塞,进入等待队列,切换到进程B,当进程B执行signal操作使进程A可以执行时,有两种方式:一种是等进程B执行完再执行进程A,另一种是立即切换到进程A,等执行完进程A再切换到进程B,执行进程B。

        第二种比第一种多了一次切换,所以第一种比较高效,但第二种容易证明其正确性。第一种主要用于真实OS和Java中,第二种主要见于教材中。

         

    四、哲学家就餐问题

      

       方案1:都先拿左边的叉子,再拿右边的叉子,拿不到就等着。当5个哲学家同时拿起左边的叉子时,就会引起死锁。

         

        方案2:某一时间内,只能有一个哲学家在进餐,其他的人都不许拿叉子。结果正确,但是效率低。

         

        方案3:按某一规律(下图是按奇偶数分类)让不同的哲学家先拿不同方向的叉子,即不是都先拿左手的叉子或右手的叉子,而是有的先拿左手的叉子,有的先拿右手的叉子。从而避免方案1中死锁的发生。

         

    五、读者写者问题

       

       

       

         

        

        

        

        

  • 相关阅读:
    Django 2.0官方文档中文 渣翻 总索引(个人学习,欢迎指正)
    Deep Learning 之 最优化方法
    2018校招笔试真题汇总
    Java Swing 图形界面开发(目录)
    【目录】Spring 源码学习
    【剑指Offer学习】【所有面试题汇总】
    SSM框架学习思维导图
    关于P2P架构的网络游戏
    Styling FX Buttons with CSS
    JavaFx2.0中CSS的应用
  • 原文地址:https://www.cnblogs.com/kkkkkk/p/5543799.html
Copyright © 2011-2022 走看看