一、回顾知识点

这一章第一节说过,进程具有【异步性】

  • 【异步】:就是各进程并发交替的运行,宏观上同时运行,不会一个等另一个执行完才运行;各个进程是按未知的速度前进的。
  • 【同步】:必须等上一个进程全部执行完了,才能到下一个进程执行

二、同步互斥概念

【临界资源】

要注意一定要遵守【临界区资源互斥准则】

        那么我们结合前面【同步】的概念,同步就是限制一个进程先执行完再到另一个进程,不可以穿插,那不正好适用于【临界资源】吗,所以【对临界资源访问】——————要采取【同步互斥机制

三、互斥具体实现

1、软件实现

那就当成我们写得代码就行了,我们在逻辑上规定好访问的进程对临界资源访问的流程

简单来说,逻辑就是:

  • 【上锁,不让别的进程用】—>
  • 【该进程进入临界区,访问临界资源】—>
  • 【解锁,让别的进程也能用】—>
  • 【做其他处理(可有可无,非考试重点)】

【具体三大算法】

1)单标志法

要记住:

  • 可能违背【空闲让进原则】
  • 必须得2个进程都有意愿使用资源,并交替运行

;

;

2)双标志先检查法

要记住:

  • 【判断是否可访问的依据是:对方用不用,用就谦让】
  • 可能违背【忙则等待原则】

;

;

3)双标志后检查法

要记住:

  • 先【更改自己的flag值为“true”】,再【判断对方flag值,对方用就谦让】
  • 可能【互相谦让,一起循环等待饿死】

4)Peterson算法(无敌了)

要记住:

  • 结合【单标志法】+【双标志后检查法】
  • 依旧先【更改自己的flag值、turn公共值】,再【判断对方flag && 公共turn】
  • 解决【饥饿问题】!!!
  • 但也违背了【让权等待】!!!
    • (因为有while循环,如果你没有资格进入临界区,你只会一直在while循环,也不能修改flag值让出位置给别的进程)
    • (但其实可以发现前面几个算法都有while循环,其实都违背了【让权等待】,只不过它不是最主要的特点)

【总结】

2、硬件实现

【前提说明】

原理就是:只用一句【机器指令】,完成一系列不可中断的原子操作,来实现进程上锁

这里需要特别说明:

  • 1、【机器指令】是一整条直接执行完毕,具有【原语性】不可以被中断
    • 而下面我们写得代码是按人的逻辑来解释:
      • 这个机器指令做了哪些步骤,而并非真的按代码一句一句执行
  • 2、【软件实现】的各个进程代码可以并发穿插执行,但是【硬件机器指令】不行

1)关中断指令

        老朋友,再熟悉不过了,【关中断】就是一种【原语指令】,屏蔽掉中断而让当前进程一直执行,其他进程再怎么发I/O请求而触发中断,人家都闭门造车听不见,直到【开中断指令】,没啥好说的

2)TS指令

全名【Test and Set指令】或【TSL指令】

结合进程的“软件实现”代码,整体流程如下:

【核心思想】就是机器指令里【记录锁状态】的同时、【保持上锁】

  • 这样的好处就是:
    • 如果被其他进程上锁了,既能检测出被上锁,又能保持上锁状态不变
    • 如果资源是空闲解锁状态,那马上检测到并上锁,然后自己使用该资源

3)Swap指令

又称【exchange指令】、【EXCH指令】,顾名思义就是【交换】

交换什么:【资源锁的状态lock】和【进程的key: 记录lock旧值】

  • 注意:
    • 【lock】是全局变量,资源的上锁、解锁状态,任何进程都可以检测到
    • 【key】是局部变量,只在一个进程内有效,进程A的key和进程B的key值不一样

结合进程的“软件实现”代码,整体流程如下:

【总结】

3、互斥锁(Mutex)

1)概念

前面我们讲了【软件互斥逻辑】【硬件互斥指令】

        那么我们在写代码的时候也知道,想要使用重复的某一功能代码,我们通常不会选择一大段代码重新复制粘贴好几次、或者重写好几次;也不会希望直接接触底层硬件逻辑,编写操作系统的指令代码

        所以就有了【互斥锁Mutex】,可以理解为【软件互斥逻辑】【硬件互斥指令】封装起来的【接口】,我们无需关心里面的代码逻辑、硬件实现,只需要在进入临界区的时候用上【互斥锁上锁】,离开临界区的时候【解开互斥锁】

2)实际如何使用

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐