一、基本概念
1.临界区
进程中访问临界资源的一段需要互斥执行的代码
2.进入区
* 检查可否进入临界去的一段代码
* 如可进入,设置相应的“正在访问临界区”标志
3.退出区
清除“正在访问临界区”
4.剩余区
代码中的其余部分
二、临界区的访问规则
1.空闲则入
没有进程在临界区时,任何进程可以进入
2.忙则等待
有进程在临界区时,其他进程均不能进入临界区
3.有限等待
等待进入临界区的进程不能无限等待下去
4.让权等待
不能进入临界区的进程,应释放CPU
三、临界区的实现方法
1.禁用中断
没有中断,没有上下文切换,因此没有并发
* 硬件将中断处理延迟到中断被启用之后
* 现代计算机体系结构都提供指令来实现禁用中断
进入临界区
* 禁止所有中断,并保存标志
离开临界区
* 使能所有中断,并保存标志
缺点:
禁用中断后,进程无法被停止
临界区可能很长
2.软件方法:Pererson算法
满足两个线程之间互斥的经典的基于软件的解决方法
软件方法的分析:
* 复杂:需要两个进程间的共享数据项
* 需要忙则等待:浪费CPU时间
3.更高级的抽象方法
3.1 锁:抽象的数据结构
* 一个二进制变量(锁定/解锁)
* Lock::Acquire()
* 锁被释放前一直等待,然后得到锁
* Lock::Release()
* 释放锁,唤醒任何等待的进程
使用锁来控制临界区的访问
3.2 原子操作指令
现代CPU体系都提供一些特殊的原子操作指令
测试和置位指令
* 从内存单元中读取值
* 测试该值是否为1(然后返回真或假)
* 内存单元值设置为1
交换指令
原子操作指令锁的特征:
优点
* 适用于单处理器或者共享主存的多处理器中任意数量的进程同步
* 简单并且容易证明
* 支持多临界区
缺点
* 忙等待消耗处理器时间
* 可能导致饥饿(进程离开临界区时有多个等待进程的情况)
* 死锁
* 拥有临界区的低优先级进程
* 请求访问临界区的高优先级进程获得处理器并等待临界区
四、同步方法总结
锁是一种高级的同步抽象方法
* 互斥可以使用锁来实现
* 需要硬件支持
常用的三种同步实现方法
* 禁用中断(仅限于单处理器)
* 软件方法(复杂)
* 原子操作指令(单处理器或多处理器)