首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

信号量与管程

信号量与管程

一、概述
 信号量是操作系统提供的一种协调共享资源访问的方法。和用软件实现的同步比较,软件同步是平等线程间的的一种同步协商机制,不能保证原子性。而信号量则由操作系统进行管理,地位高于进程,操作系统保证信号量的原子性。
   信号量是跟锁机制在同一个层次上的编程方法。
   管程是为了解决信号量在临界区的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还是分散的啊。求指教)
继承事业,薪火相传
返回列表