操作系统的信号量和管程

原创 2016年05月20日 19:06:21

信号量 semaphore
信号量是操作系统提供的一种协调共享资源访问的方法
软件同步是平等线程间的一种同步协商机制
OS是管理者,地位高于进程
用信号量表示系统资源的数量

由一个整形 (sem)变量和两个原子操作组成
P()(Prolaag (荷兰语尝试减少))
sem减1
如sem<0, 进入等待, 否则继续
V()(Verhoog (荷兰语增加))
sem加1
如sem≤0,唤醒一个等待进程

P() 可能阻塞,V()不会阻塞,这些只能在内核实现,而不能在用户实现。

信号量的使用:
(1) 同步 线程间的事件等待
(2) 互斥 临界区的互斥访问控制
用信号量实现临界区的互斥访问必须成对使用P,V操作 ,不能次序错误、重复或者遗漏

条件同步:初值设为0

自旋锁不能实现先进先出:
它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,”自旋”一词就是因此而得名。
跟互斥锁一样,一个执行单元要想访问被自旋锁保护的共享资源,必须先得到锁,在访问完共享资源后,必须释放锁。如果在获取自旋锁时,没有任何执行单元保持该锁,那么将立即得到锁;如果在获取自旋锁时锁已经有保持者,那么获取锁操作将自旋在那里,直到该自旋锁的保持者释放了锁。由此我们可以看出,自旋锁是一种比较低级的保护数据结构或代码片段的原始方式,这种锁可能存在两个问题:
死锁。试图递归地获得自旋锁必然会引起死锁:递归程序的持有实例在第二个实例循环,以试图获得相同自旋锁时,不会释放此自旋锁。在递归程序中使用自旋锁应遵守下列策略:递归程序决不能在持有自旋锁时调用它自己,也决不能在递归调用时试图获得相同的自旋锁。此外如果一个进程已经将资源锁定,那么,即使其它申请这个资源的进程不停地疯狂“自旋”,也无法获得资源,从而进入死循环。
过多占用cpu资源。如果不加限制,由于申请者一直在循环等待,因此自旋锁在锁定的时候,如果不成功,不会睡眠,会持续的尝试,单cpu的时候自旋锁会让其它process动不了. 因此,一般自旋锁实现会有一个参数限定最多持续尝试次数. 超出后, 自旋锁放弃当前time slice. 等下一次机会
由此可见,自旋锁比较适用于锁使用者保持锁时间比较短的情况。正是由于自旋锁使用者一般保持锁时间非常短,因此选择自旋而不是睡眠是非常必要的,自旋锁的效率远高于互斥锁。信号量和读写信号量适合于保持时间较长的情况,它们会导致调用者睡眠,因此只能在进程上下文使用,而自旋锁适合于保持时间非常短的情况,它可以在任何上下文使用。如果被保护的共享资源只在进程上下文访问,使用信号量保护该共享资源非常合适,如果对共享资源的访问时间非常短,自旋锁也可以。但是如果被保护的共享资源需要在中断上下文访问(包括底半部即中断处理句柄和顶半部即软中断),就必须使用自旋锁。自旋锁保持期间是抢占失效的,而信号量和读写信号量保持期间是可以被抢占的。自旋锁只有在内核可抢占或SMP(多处理器)的情况下才真正需要,在单CPU且不可抢占的内核下,自旋锁的所有操作都是空操作,

与前面的区别 P,V代码的原子性由操作系统保护。

必须成对使用P,V
如果不申请(P操作),直接V操作:就会有多个线程进入到临界区
如果申请了(P不操作),不释放(V):谁都不能进入临界区

不能避免死锁的出现,必须在写程序的时候解决这个问题。
sim++:(保证操作正确性)
TestAndSet(&lock),等价exchange
中断
软件处理
* 实现条件同步:线程A在线程B后执行
信号量初始值:0
信号量解决生产者,消费者问题
emptyBuffers->P()
mutex->P(); 两者交换,程序出现死锁

mutex-V()
fullBuffers->V()两者交换顺序,对程序正确性没有任何影响。

第二种同步方法:管程
信号量:P,V 操作分配在生产者与消费者中,P,V的配对是比较困难的。
信号量使用锁,管程使用条件变量,在解决同步互斥问题上,信号量与管程等价。
管程:P,V操作的配对,集中在一起
(1)管程采用面向对象的方法,简化了线程间的同步控制。
(2)任何时刻只有一个线程在执行管程代码
(3)临界区也是任何时刻只有一个线程在执行管程代码,但是他们有区别,区别是:正在管程中的线程可临时放弃管程的互斥访问,等待事件出现时恢复。

管程的使用:
在对象、模块中收集相关共享的数据
定义访问共享数据的方法,在其他地方不需要同步互斥操作了。
管程也可能出现死锁的情况
管程中的局部变量不可以被外部直接访问
管成组成:
一个锁(入口,出口)
控制管程代码的互斥访问
0或者多个条件变量
管理共享数据的并发访问
临界区只有一个条件变量,而管程管理一系列的条件变量

条件变量
条件变量是管程内的等待机制
进入管程的线程因资源被占用而进入等待状态
每个条件变量表示一种等待原因,对应一个等待队列
Wait()操作
将自己阻塞在等待队列中
唤醒一个等待者或释放管程的互斥访问
与信号量区别:不用判断sim/numWaiting是否为空,直接加入waitQueue 中,而且不用管配对的问题。
Signal()操作
将等待队列中的一个线程唤醒
如果等待队列为空,则等同空操作
用管程解决生产者-消费者问题
效率不如信号量的效率

读者、写者问题:
规则:“读-读“允许 “写-读”互斥” ‘ “写-写”互斥

管程实现读者-写者问题
AR=0 Active readers 当前正在读的读者
AW=0 当前正在写的写者
WR=0 当前等待的读者
WW=0 当前等待的写者

读者-写者问题 (考试实现读者优先),
读者优先
写者端: StrarWrite() while(while(AR+WR>0)){okToWrite.wait()}
DoneWrite() if(AW==0&&WR>0){okToRead.signal()}

读者端:
StartRead() while(AW+AR>0){okToRead.wait()}
DoneRead() if(WR>0){okToRead.signal()}else if(WW>0){okToWrite.signal()}

写者优先
读者端:
stratRead()函数:while(AW+WW>0){ okToReda.wait()}
DoneRead()函数: if(AR==0&&WW>0) //没有读者且有写者等着则释放锁
oktowrite.signal()

写者端:
startWrite() while((AW+AR)>0){ okToWrite.wait} 但是有等待读的读者,是不等的,则说明是写者优先的
DoneWrite if(WW>0){okToWrite.signal()}else if(WR>0){okToRead.broadcast()}

版权声明:本文为博主原创文章,未经博主允许不得转载。

操作系统的信号量 进程互斥 同步等概念

摘 要: 本文针对目前操作系统中利用信号量解决进程间的同步和互斥的问题,系统地总结了解决问题的一般性规律。首先介绍了信号量的定义及在信号量上可以执行的两个操作,并分别详细说明了如何利用信号量实现进程...
  • lujiandong1
  • lujiandong1
  • 2015年03月23日 08:39
  • 3322

操作系统中的信号量(sema)与互斥(mutex)

信号量:那是多线程同步用的,一个线程完成了某一个动作就通过信号告诉别的线程,别的线程再进行某些动作。 互斥量:这是多线程互斥用的,比如说,一个线程占用了某一个资源,那么别的线程就无法访问,知道这...
  • u014379540
  • u014379540
  • 2016年08月28日 15:37
  • 1282

操作系统之-----信号量机制

信号量机制是一种卓越成效的进程同步工具,信号量机制已经被广泛的使用于单处理机,和多处理系统的计算机网络中。 信号量S是一个整数,S大于等于零代表可供并发进程使用的资源实体数,当S小于零时则表示正在等...
  • WannerWang
  • WannerWang
  • 2015年11月01日 10:40
  • 1726

深入理解l操作系统的管程,进程,线程(一)

1.管程(monitors)的引入和定义
  • u014309268
  • u014309268
  • 2014年09月15日 05:36
  • 3041

信号量与管程

基本同步方法 信号量semaphore:操作系统提供的一种协调共享资源访问的方法:OS是管理者,地位高于进程;信号量表示系统资源的数目。是一种抽象的数据类型:一个整形变量sem和两个原子操作(p()...
  • zhouzhou135
  • zhouzhou135
  • 2015年06月04日 21:19
  • 1170

操作系统---->作业、进程、线程、管程、管道概念梳理

作业:用户在一次解决或是一个事务处理过程中要求计算机系统所做的工作的集合,它包括用户程序、所需要的数据集控制命令等。作业是由一系列有序的步骤组成的。在执行一个作业可能会运行多个不同的进程。     ...
  • linmars24
  • linmars24
  • 2012年07月30日 22:37
  • 2608

操作系统概念 管程Java代码实现

java中利用管程实现同步互斥量其实我关于代码中信号量和管程的具体差别不是特别的清楚。 但是因为用到了Semaphore类(信号量),就是用信号量实现的。程序员们需要自己对信号量的初始化、更新(wa...
  • u013007900
  • u013007900
  • 2015年11月29日 20:43
  • 1816

【操作系统原理】信号量机制

信号量机制是一种卓有成效的进程互斥同步工具。这里只介绍记录型信号量机制,它可以有效的解决CPU“忙等”的问题,实现互斥。          记录型信号量机制的数据结构如下(看不懂那些字母是什么其实...
  • LDan508
  • LDan508
  • 2016年03月13日 23:17
  • 3502

操作系统之信号量

信号量的定义: 为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域。临界区域是指执行数...
  • E01014165
  • E01014165
  • 2016年08月19日 11:00
  • 396

信号量函数(semget、semop、semctl)及其范例

信号量函数由semget、semop、semctl三个函数组成。下面的表格列出了这三个函数的函数原型及具体说明。1.   semget函数原型semget(得到一个信号量集标识符或创建一个信号量集对象...
  • guoping16
  • guoping16
  • 2011年07月04日 17:34
  • 30013
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:操作系统的信号量和管程
举报原因:
原因补充:

(最多只允许输入30个字)