一、同步与互斥的概念
异步性 是指,各并发执行的进程以各自独立的、不可预知的速度向前推进。进程具有 异步性 的特征,因此操作系统要提供 进程同步机制 来解决异步问题。此外,有些资源 一个时间段内只允许一个进程访问,操作系统要使得进程 互斥的访问 来该资源。
1.1 同步与互斥的基本概念
进程同步
同步,亦称 直接制约关系。进程同步 是指在某些时刻为完成某种任务而使得多个进程协调工作(互相发送消息、进行互相合作、互相等待,按照一定速度执行)而产生的 制约关系。(如:管道通信中,一定是先写在读)
进程互斥
互斥,亦称 间接制约关系。进程互斥 是指当一个进程访问某临界资源时,另一个想要访问该临界资源的进程必须等待(只有申请到锁才可以访问)。当前访问临界资源的进程访问结束,释放该资源之后,另一个进程才能去访问临界资源。(如:访问打印机)
1.2两种资源共享方式
共享方式有两种,分别是:互斥共享方式 、 同时共享方式。其中,互斥共享方式 对应 临界资源,同时共享方式 对应 共享资源 。
互斥共享方式:一个时间段内 只允许一个进程 访问。
同时共享方式:允许一个时间段内 可由多个进程 “同时” 访问。
临界资源
将一次只允许一个进程使用 的资源称为 临界资源。许多物理设备都属于临界资源
共享资源
将一次允许多个进程同时使用 的资源称为 共享资源。如:输出一行字符。
常见的临界资源与共享资源
临界资源:打印机、共享变量、共享缓冲区、公用队列。
共享资源:磁盘、非共享变量、可重入的代码。
1.3同步机制要遵循的原则
为了实现对临界资源的互斥访问,同时保证系统整体性能,需要遵循以下原则:
① 空闲让进:临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区;
② 忙则等待:当已有进程进入临界区时,其他试图进入临界区的进程必须等待;
③ 有限等待:对请求访问的进程,应保证能在有限时间内进入临界区(保证不会饥饿);
④ 让权等待:当进程不能进入临界区时,应立即释放处理机,防止进程忙等待。
二、实现临界区互斥的基本方法
2.1 软件实现方法
2.1.1 单标志法
该算法可以实现“在同一时刻最多只允许一个进程访问临界区”
算法基本思想:俩个进程在自己访问临界区后把权限交给另一个进程,也就是说进入临界区的权限只能有另一个进程赋予。
设置一个 公用变量 turn,用于指示被允许 进入临界区的进程编号,即若 turn = 0,则允许 P0 进程进入临界区。算法可保证同一时刻只允许一个进程进入临界区,但两个进程必须交替进入临界区。
缺点:该算法先让P0进入访问区,再有P1进入,然后轮流访问。若P0一开始不进行访问,P1只能卡在就绪中,只能等P0访问结束后才能进行访问,若P0一直不访问,则P1只能一直等待(这时候CPU处于空闲阶段)。违背了“空闲让进”的原则。
2.1.2 双标志先检查法
算法基本思想:设置 一个布尔型数组 flag[],数组中各个元素用来标记各进程想 进入临界区的意愿,比如 flag[0] = ture 意味着 0 号进程 P0 现在想要进入临界区。每个进程在进入临界区之前先检查当前有没有其他进程想进入临界区,如果没有,则把自身对应的标志 flag[i] 设为 true,之后开始访问临界区。
存在问题:若按照 ①⑤②⑥…. 的顺序执行,P0 和 P1 将会同时访问临界区,违背 “忙则等待” 原则。原因在于,进入区的 检查 和 上锁 两个处理不是 一气呵成, 先检查后上锁,在 检查后 和 上锁前 可能发生进程切换。
2.1.3 双标志后检查法
算法基本思想:双标志先检查法的改版,与前一个算法不同,采用 先上锁后检查,来避免上述问题。
存在问题:若按照 ①⑤②⑥…. 的顺序执行,P0 和 P1 将都无法进入临界区。因此,双标志后检查法虽然 解决了 “忙则等待” 的问题,但是 又违背了 “空闲让进”和“有限等待” 原则,会因各进程都长期无法访问临界资源而产生 饥饿 现象。两个进程都争着想进入临界区,但是谁也不让谁,最后谁都无法进入临界区。
2.1.4 Peterson 算法
算法基本思想:结合双标志法、单标志法的思想。如果双方都争着想进入临界区,那可以让进程尝试 孔融让梨(谦让),做一个有礼貌的进程。进程在进入区要做的步骤: ① 主动争取 ② 主动谦让 ③ 检查对方是否也想使用,且最后一次是不是自己说了客气话
存在问题:Peterson 算法用软件方法解决了进程互斥问题, 遵循 “空闲让进”、“忙则等待”、“有限等待” 三个原则,但是依然 未遵循 “让权等待” 的原则。
2.1.5 软件实现方法总结
2.2 硬件实现方法
2.2.1 中断屏蔽法
中断屏蔽法利用 “开/关中断指令” 实现,即在某进程开始访问临界区到结束访问为止都不允许被中断,也就不能发生进程切换,因此也不可能发生两个进程同时访问临界区的情况。
优点: 简单、高效
缺点: 不适用于多处理机。只适用于 OS内核进程,不适用于用户进程。(因为开/关中断指令只能运行在内核态,这组指令如果能让用户随意使用会很危险)
2.2.4 补充:互斥锁
解决 临界区 最简单的工具就是 互斥锁 (mutex lock)。一个进程在进入临界区时应 获得锁,在退出临界区时 释放锁 。函数 acquire() 获得锁,而函数 release()释放锁。
每个互斥锁有一个布尔变量 available,表示锁是否可用。如果锁是可用的,调用 acqiure()会成功,且锁不再可用。当一个进程试图获取不可用的锁时,会被阻塞,直到锁被释放。acquire() 或 release() 的执行必须是 原子操作,因此 互斥锁通常采用硬件机制来实现。
优点: 等待期间不用切换进程上下文,多处理器系统中,若上锁的时间短,则等待代价很低。当多个进程共享同一 CPU时,就浪费了CPU 周期。因此,互斥锁通常用于多处理器系统,一个线程可以在一个处理器上等待,而不影响其他线程的执行,并快速释放临界区。
缺点:不满足 “让权等待” 原则。当有一个进程在临界区中,任何其他进程在进入临界区时必须连续循环调用 acquire(),因此会发生 忙等待。
原文链接:https://blog.csdn.net/weixin_43819566/article/details/128782933