- 操作系统教程
- 操作系统 - 首页
- 操作系统 - 需求
- 操作系统 - 概述
- 操作系统 - 历史
- 操作系统 - 组成部分
- 操作系统 - 结构
- 操作系统 - 架构
- 操作系统 - 服务
- 操作系统 - 属性
- 操作系统 - TAT & WAT
- 操作系统进程
- 操作系统 - 进程
- 操作系统 - 进程调度
- 操作系统 - 调度算法
- 先来先服务 (FCFS) 调度算法
- 最短作业优先 (SJF) 调度算法
- 轮询调度算法
- 最高响应比优先 (HRRN) 调度算法
- 优先级调度算法
- 多级队列调度
- 上下文切换
- 进程操作
- 彩票进程调度
- 预测突发时间 SJF 调度
- 竞争条件漏洞
- 临界区同步
- 互斥同步
- 进程控制块
- 进程间通信
- 抢占式和非抢占式调度
- 操作系统同步
- 进程同步
- 操作系统内存管理
- 操作系统 - 内存管理
- 操作系统 - 虚拟内存
- 操作系统存储管理
- 操作系统 - 文件系统
- 操作系统类型
- 操作系统 - 类型
- 操作系统杂项
- 操作系统 - 多线程
- 操作系统 - I/O 硬件
- 操作系统 - I/O 软件
- 操作系统 - 安全
- 操作系统 - Linux
- 考试题库及答案
- 考试题库及答案
- 操作系统有用资源
- 操作系统 - 快速指南
- 操作系统 - 有用资源
- 操作系统 - 讨论
同步中的临界区
什么是临界区?
临界区指的是进程中一段代码,这段代码会改变任何共享资源的值或状态。共享资源指的是共享内存变量、公共表、共享文件、共享设备或任何其他系统资源。
这段代码被称为“临界区”,因为如果多个进程同时尝试操作共享资源,则由于一种称为竞争条件的现象,结果将不一致。
临界区问题
临界区问题在于设计一种协议,使得当一个进程正在执行其临界区时,不允许其他进程同时执行其临界区,从而避免发生竞争条件。
为了实现这种合作,每个进程都必须请求进入其临界区的许可。进程进行此操作的代码段称为入口段。如果进程获得许可,则它进入临界区,在临界区中,它更新共享资源的值。
临界区之后,进程通过退出段,在退出段中,它放弃对共享资源的控制并将其告知系统中的其他进程。然后,进程继续执行其剩余语句。下图显示了具有临界区的进程的一般结构。
临界区问题解决方案的要求
任何针对临界区问题的解决方案都需要满足以下三个要求:
1. 互斥
互斥意味着任何时候只有一个进程可以在临界区内。如果其他进程需要执行其临界区,则必须等待临界区空闲。
2. 进程推进
当没有任何进程当前在其临界区中,而某些进程想要进入其临界区时,只有不在其剩余段中的进程才能参与决定哪个进程可以接下来进入其临界区,并且此决定不能无限期推迟。进程推进确保进程之间有公平的仲裁,以便进程继续执行。
3. 有界等待
有界等待意味着每个进程必须有有限的等待时间。它不应该无限期地等待访问临界区。它为当一个进程请求其临界区的许可时其他进程可以访问临界区的次数设置了一个界限。
解决临界区问题的算法和方法
为了解决临界区问题,已经开发了许多算法和方法。一些最常见的解决方案列在下面。
1. Peterson 算法
Peterson 算法是一种经典的基于软件的方法,用于确保并发进程之间的互斥。它使两个进程能够访问共享资源而不会发生冲突,依靠共享内存进行通信。该算法使用两个共享变量,即 flag 用于指示一个进程对进入临界区的兴趣,turn 用于确定如果两个进程都感兴趣时的优先级。
2. 测试并设置
此方法使用一个共享布尔变量,称为“锁”,其中 lock = true 表示一个进程在其临界区中。每个进程的入口段都有一个原子函数“测试并设置”,它检查 lock 的值。如果 lock 为 true,则等待。否则,它将 lock 设置为 true 并进入临界区。在退出段中,lock 重置为 false。
3. 信号量
信号量是一种高级同步工具。它使用两个原子操作,“wait()”和“signal()”。wait() 指令用于在入口段中获取对临界区的访问权限,而 signal() 操作用于释放对共享资源的控制。信号量可以分为两种类型:二进制信号量和计数信号量。
4. 比较并交换
此方法类似于“测试并设置”方法。它使用一个共享布尔变量,其值使用“比较并交换”指令进行测试和设置。只有当传递给它的值与某个值匹配时,锁才设置为 true。
5. 互斥锁
互斥一词源于互斥。它使用锁,这些锁分别在入口段和退出段中使用原子函数“acquire()”和“release()”进行操作。一次只有一个进程可以获取锁,因此一次只有一个进程可以访问临界区。
操作系统内核中解决临界区问题的方法
与用户进程一样,许多内核进程也并发执行,它们可能尝试更新内核数据结构的值。内核数据是共享数据结构,包括进程列表、内存分配、打开文件列表、中断处理等。尝试更新这些值会导致出现许多竞争条件情况的可能性很高。操作系统竞争条件比用户进程中发生的竞争条件更关键,可能会导致系统崩溃。因此,内核开发者需要细致的设计策略来避免内核竞争条件。
操作系统中的内核大致分为抢占式和非抢占式两种。让我们来看看在两者中解决竞争条件的一般方法。
非抢占式内核
非抢占式内核本质上没有竞争条件。在这里,在内核模式下运行的进程不会被任何其他进程抢占。它将继续运行,直到它退出、阻塞或自愿放弃 CPU 的控制权。由于任何给定时间只有一个进程在内核中处于活动状态,因此非抢占式内核不容易在内核数据结构上出现竞争条件。
抢占式内核
在抢占式内核中,正在执行的内核进程可能会中途停止,另一个进程可能会开始运行。这可能会破坏内核数据结构的值。抢占式内核对于实时系统至关重要,因为它们具有更高的响应能力和吞吐量,因此不能被非抢占式内核取代。因此,它们需要采取足够的措施来处理内核临界区。
一个常见的解决方案是使用自旋锁代码。当内核进程持有自旋锁时,相应处理器的抢占或中断将被暂时禁用。进程执行其临界区代码,然后释放自旋锁。一旦自旋锁被释放,中断将再次启用。由于禁用中断可能会产生许多不利后果,因此目标是通过任何进程来最小化持有自旋锁的时间。