操作系统中对信号量的保护

本文探讨了操作系统中对信号量保护的重要性,分析了临界区问题的解决方案,包括软件实现的轮换法、标记法、Peterson算法和Lamport面包店算法,以及硬件实现的关中断和硬件原子指令法。通过这些方法,可以确保信号量操作的原子性,满足互斥性、有空让进和有限等待的要求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

操作系统中对信号量的保护

背景

信号量的引入使得线程/进程之间同步活动。但是对于操作信号量的接口调用代码必须是原子的,否则可能会使得信号量的内容不能够反映出资源的真实情况。这种必须为原子操作的代码块称为临界区(CS, critical section)。即,不同线程/进程中(以下将线程和进程统称为进程,因为在本文讨论的内容中它们没有区别)没有两个任务可以在它们的临界区内同时执行。

对信号量的保护便属于一个临界区问题(critical-section problem),对于临界区问题的解决方案应同时满足以下三个要求:

  • 互斥进入(mutual exclusion, 简写为mutex):如果进程Pi在其临界区内执行,那么其他进程都不能在其临界区内执行。
  • 有空让进(progress):如果没有进程处于临界区内且有进程请求进入临界区,则应该能让某个请求进程进入临界区执行,即不发生资源的死锁情况。
  • 有限等待(bounded waiting):当一个进程提出进入临界区请求后,最多需要等待临界区被使用有限次以后,该进程就可以进入临界区。这样,任何一个进程对临界区的等待时间都是有限的,即不出现因等待临界区而造成的饥饿情况。

解决方案(软件实现)

1.轮换法与标记法

采用轮换法,任何时候就只有一个进程有权利进入临界区,只有这个进程退出临界区后才能轮换到其他进程,显然这满足了互斥性。其代码如下:
在这里插入图片描述
以P0为当前进程为例,如果它发现现在轮到的是P1而不是自己,则不停地自旋等待直到时间片用尽切换到进程P1;P1发现现在是轮到自己,于是执行CS代码段,执行完后将turn置为0表示该轮到P0了。

轮换法只是一个简单prototype,其的缺点是很明显的。比如:P0得到进入CS代码段的决定权在P1中,如果P1进程被销毁,则P0则不再可能获得进入CS的机会。即,轮换法没有实现有空让进。

标记是另一种朴素的解决方法。进程P0想要进入CS就做一个标记。做完标记以后扫描其他进程是否要进入CS,如果有这样的进程,则P0自旋等待。其代码如下:
在这里插入图片描述

这种方案显然也是不可行的,如果两个进程都想进入CS,它们就会互相等待而没任何一个可以进入CS,即出现了死锁,无法满足有限等待。

这两种朴素解决方案各自可以解决三个要求中的两个,将它们进行简单的组合便可以同时满足三个要求,这就是Peterson算法。

2.Peterson算法

在这里插入图片描述

还是从进程P0出发,其想要进入CS,则将其flag置为1,同时将访问权设为P1而不是自己,此时如果P1也想进入则进入自旋等待。过了一会P0的时间片用尽,操作系统调度到进程P1,P1从头开始执行,将自己的flag置为1,将访问权设为P0,然后也进入自旋等待。过了一会再调度到P0执行,此时的turn已经被进程P1设置为P0,所以P0可以进入CS。其进入CS后将自己的flag再置为false,P1得以进入CS。

上面讨论的这种执行顺序(事实上有很多可能的执行顺序)有点像两个人在互相谦让,A对B说:虽然我想访问,但还是你先来吧;B对A说,虽然我也想访问,但还是你先来吧;A不再推辞,便进行了访问。A访问后B也得到了访问的机会。

下面来看看Peterson算法是否满足临界区问题的三个要求。
一、互斥性:假设P0和P1能够同时执行CS的代码,则显然turn即等于1又等于0,所以显然是不可能的。所以满足互斥性
二、有空让进:假如两个进程中有一个不想进入临界区,则另一个进程便不会自旋等待,可以进入临界区。假如两个进程都想进入临界区,那么按照上面的讨论得知会有一个进程可以进入临界区。所以满足有空让进。
三、有限等待:假设操作系统不断地调度到P1,那么在P1执行完CS的代码后,会将flag置为0,。此时P1再次执行的话就会不停地自旋等待,从而可以调度到其他生产

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值