1.同步,互斥基本概念
1.1 进程同步
并发性带来了异步性下,有时需要通过进程同步来解决这种异步问题.有的进程之间需要相互配合地完成工作,各进程的工作推进需要遵循一定的先后顺序.
1.2 进程互斥
1.2.1 对临界资源的访问,需要互斥的进行.
同一时间只能允许一个进程访问该资源
1.2.2 四个部分
1> 进入区: 检查是否可以进入临界区,若可以则要上锁
2> 临界区: 访问临界资源的那段代码
3> 退出区: 负责解锁
4> 剩余区: 其余代码部分
1.2.3 需要遵循的原则
1> 空闲让进: 临界区空闲时,应允许一个进程访问
2> 忙则等待: 临界区正在被访问时,其他试图访问的进程需要等待
3> 有限等待: 要在有限时间内进入临界区,保证不会饥饿
4> 让全等的: 进不了临界区的进程,需要释放处理机,防止忙等(当一个进程需要等待某个资源或事件(如 I/O 操作完成、信号量变为可用等),它可以主动放弃 CPU 的使用权,进入等待状态,从而允许其他就绪的进程运行。)
总:
2.进程互斥的软件实现方式
2.1 单标志法
概念: 两个进程在访问完临界区后会把使用临界区的权限转交给另一个进程。也就是说每个进程进入临界区的权限只能被另一个进程赋予
1> 在进入区只做"检查"不"上锁"
2> 在退出区把临界区的使用权交给另一个进程
3> 主要问题: 不遵循空闲让进的原则
2.2 双标志先检查
概念: 设置一个布尔型数组 flag[],数组中各个元素用来标记各进程想进入临界区的意愿,比如“flag[0] = ture”意味着 0 号进程 P0 现在想要进入临界区。每个进程在进入临界区之前先检查当前有没有别的进程想进入临界区,如果没有,则把自身对应的标志 flag[i] 设为 true,之后开始访问临界区
1> 在进入区前线检查后上锁,退出区解锁
2> 主要问题: 不遵循忙则等待的原则
2.3 双标志后检查
概念: 双标志先检查法的改版。前一个算法的问题是先“检查”后“上锁”,但是这两个操作又无法一气呵成,因此导致了两个进程同时进入临界区的问题。因此,人们又想到先“上锁”后“检查”的方法,来避免上述问题
1> 在进入区先加锁后检查,退出区解锁
2> 主要问题: 不遵循空闲让进,优先等等原则,可能导致饥饿
2.4 Peterson算法
概念: 结合双标志法、单标志法的思想。如果双方都争着想进入临界区,那可以让进程尝试“孔融让梨”(谦让)。做一个有礼貌的进程.
1> 在进入区"主动争取-主动谦让-检查对方释放想进,自己是否谦让"
2> 主要问题:不遵循"让权等待"原则,则会发生忙等
3.进程互斥的硬件实现方式
3.1 中断屏蔽方法
1> 使用"开/关中断"指令实现
2> 优点: 简单高效
3> 缺点: 只适合单处理机;只适用于操作系统内核进程
3.2 TestAndSet(TS指令/TSL指令)
1> old是否上锁,在把lock设为true,检查临界区是否上锁(若上锁重复前几步)
2> 优点: 实现简单;适合多处理机环境
3> 缺点: 不满足"让权等待"
3.2 Swap指令(XCHG指令)同3.1
特性:
1> 需忙等,进程时间片用完才下处理机,违反"让权等待"
2> 优点:等待期间欸不需要上下文,多处理机中,若上锁时间断,则等待代价很低
3> 常用于多处理器系统,一个核忙等,其他核照常工作,并快速释放临界区
4.互斥锁(mutex lock)
概念: 一个进程在进入临界区的时候获得锁;退出临界区的时候释放锁.acquire()表示获得锁,release()表示释放锁.
5.信号量机制
概念:
5.1 整形信号量
1> 用一个整形变量作为信号量,数值表示某种资源数.
2> 整型信号量和普通整型变量的区别:对信号量只能执行 初始化,P,V三种操作
3> 整型信号量存在的问题: 不满足让权等待原则
5.2 记录型信号量
1> S.value 表示某种资源数,S.L指向等待该资源的队列
2> P操作中,一定是先S.value--,之后可能需要执行block原语
3> V操作中,一定是先S.value++,之后只wakeup原语
4> 可以用记录型信号量是西安系统资源的"申请"和"释放"
5> 可以用记录型信号量实现进程同步,进程互斥.
总:
6.用信号量实现进程互斥
PV操作的概念:
6.1 实现进程互斥
1> 分析问题,确定临界区
2> 设置互斥信号量,初值设为1
3> 临界区资源之前对信号量执行P操作
4> 临界区之后对信号量执行V操作
6.2 实现进程同步
1> 分析问题,找出一前一后的同步关系
2> 设置同步信号量,初始值为0
3> 在"前操作"之后执行V操作
4> 在"后操作"之前进行P操作
6.3 实现进程的前驱关系
1> 分析问题,画出前驱图
2> 为每一对前驱关系设置同步信号量
3> 在每个"前操作"之后执行V操作
4> 在每个"后操作"之前执行P操作
总:
后续还有几个算法,得好好理解,真的太难了