目录
先来先服务算法(first come first serve)
高响应比优先算法(Highest Response Ratio Next)
进程的定义
基本概念
- 程序:就是一个指令的序列
- 程序段:在内存中存放程序代码的地方,其一般放在内存的低地址处
- 数据段:在内存中存放数据的部分,程序运行时使用,其一般放在内存的高地址处
- PCB:进程控制模块,其存放在内存中,是操作系统用于管理各个进程实现并发执行的数据结构,其包含了操作系统用于管理这些正在运行程序所需要的各种各样的信息
注意:
- 操作系统在每一个程序开始执行之前都会为这个即将执行的程序分配一个PCB(进程控制模块)的数据结构
- PCB是进程存在的唯一标志
- 内存中可有多个程序段或数据段
进程实体与进程
进程实体:由PCB、程序段、数据段这三部分构成,其也称进程映像,一般来说我们可以把进程实体简称为进程。所谓的创建进程,实质上是创建进程实体中的PCB;而撤销进程,实质上就是撤销进程实体中的PCB
进程:其是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位(正在运行的程序)
PCB的组成
注意:
- 进程的标识符:当进程被创建时,操作系统会为该进程分配一个唯一的,不重复的ID,用于区分不同的进程
- 用户标识符:用于标识这个进程所属的用户是谁
- PCB中为什么保存各种寄存器的值原因:当进程切换时需要把进程当前的运行情况记录下来保存在PCB中,如程序计数器的值表示了当前程序执行到那一句
进程的组织
前言:在一个系统中,通常有数10、数百、乃至数千个PCB。为了能够对他们加以有效的管理,应该用适当的方式把这些PCB组织起来。
链接方式
理解:按照进程状态将PCB分为多个队列,操作系统持有指向各个队列的指针
索引方式
理解:根据进程状态不同建立几张索引表;操作系统持有指向各个索引表的指针
进程的特征
注意:动态性是进程最基本的特征。
进程的状态
前言:进程是程序的一次执行。在这个执行过程中,有时进程正在被CPU处理,有时又需要等待CPU服务,可见,进程的状态会有各种变化。为了方便对各个进程的管理,操作系统需要将进程划分为几种状态
进程的三种基本状态
- 运行态:已经占有CPU,并在CPU上运行(单核处理机环境下,每一个时刻最多只有一个进程处于运行态)
- 就绪态:已经具备运行条件,但是由于没有空闲CPU,进而暂时不能运行(处于就绪态下的进程已经拥有了除了处理机之外所有需要的资源,一旦获得处理机,即可立即进入运行态并开始运行)
- 阻塞态:因等待某一事件而暂时不能运行
进程的另外两种状态
- 创建态:进程正在被创建,操作系统为进程分配资源、初始化PCB
- 终止态:进程正在从系统中撤销,操作系统会回收进程拥有的资源、撤销PCB
进程状态的转换
注意:
- 运行态到阻塞态是一种进程自身做出的主动行为
- 阻塞态到就绪态不是进程自身能够控制的,其是一种被动行为
- 不能由阻塞态直接转换为运行态,也不能直接由就绪态转换为阻塞态
进程控制
何谓进程控制
含义:进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能
简单理解:实现进程状态之间的转换
如何实现进程控制
过程:
- 创建进程需要初始化PCB、分配系统资源
- 创建态到就绪态需要修改PCB内容和相应的队列
- 就绪态到运行态须恢复进程的运行环境、修改PCB内容和相应的队列
- 运行态到终止态须回收进程拥有的资源,撤销PCB
- 运行态到阻塞态须保存进程的运行环境,修改PCB内容和相应的队列
- 阻塞态到就绪态须修改PCB内容和相应的队列。若等待的是资源,则还需为进程分配系统资源
注意:进程状态的切换中间需要做的内容是比较复杂的,我们需要修改PCB内容并把PCB放到相应的队列;假如某一个进程把他的PCB从一个队列放到了另一个队列,但是我们并没有把PCB中相应的标志位修改,那么这种情况很危险,极有可能导致系统错误;为了防止这个问题的发生,于是就使用了原语来实现进程的控制。
原语
前言:原语的特点是执行期间不允许间断,只能一气呵成,这种不可以被中断的操作被称为原子操作
注意:
- 原语采用“关中断”和“开中断”指令组合实现的
- 执行了关中断指令后若外面有一个外部中断信号进入,那么该外部中断信号会被忽略,暂时不被处理;只有在执行了开中断指令后,再接收到一个外部中断信息,此时才会转入到相应的中断处理程序中开始处理
- 关/开中断指令的权限非常大,必然是只允许在核心态下执行特权指令
原语要做的事
- 更新PCB中的信息(如修改进程状态的标志、将运行环境保存在PCB、从PCB恢复运行环境)
- 将PCB插入到合适的队列
- 分配/回收资源
进程通信
前言:
- 进程是分配系统资源的单位(包括内存地址空间)因此各个进程拥有的内存地址空间相互独立
- 为了保证安全,一个进程不能直接访问另一个进程的地址空间的
含义:进程通信就是指进程之间的信息交换
注意:仅管一个进程不能直接访问另一个进程的地址空间,但是进程之间的信息交换又是必须实现的。为了保证进程间的安全通信,操作系统提供了进程通信一些方法(共享存储、消息传递、管道通信)
共享存储
含义:由于两个进程他们不能直接访问对方的地址空间,所以操作系统会为两个进程分配一个共享空间;两个进程之间的通信就可以通过共享空间来完成
注意:
- 两个进程对共享空间的访问必须是互斥的,当进程1正在往这个共享空间写数据的时候进程2是不允许访问这个共享空间的,只有进程1把这个共享空间的访问释放了,进程2才可以开始读操作
- 互斥访问通过操作系统提供的工具实现
共享存储的分类
- 基于数据结构的共享:如共享空间里只能放一个长度为10的数组;这种共享方式速度慢、限制多,是一种低级通信方式
- 基于存储区的共享:如在内存中画出一块共享存储区,数据的形式、存储的位置都由进程控制,而不是操作系统。相比之下,这种共享方式速度更快,是一种高级通信方式
管道通信
注意:
- 管道是指用于连接读写进程的一个共享文件,又名pipe文件。其实就是在内存中开辟一个大小固定的缓冲区
- 管道只能采用半双工通信,某一时间段内只能实现单向的传输,若要实现双向同时通信,则需要设置两个管道
- 各个进程对管道的访问需要互斥的(当进程1往里面写数据的时候,进程2不可以读管道里的数据)
- 数据是以字符流的形式写入管道的,当管道写满时,写进程的write()系统调用将会被阻塞,等待读进程将数据取走。当读进程将数据取走后,管道变空,此时读进程的read()系统调用将会被阻塞
- 若管道没有写满,则不允许读;若没读空,则不允许写
- 数据一旦被读出,就从管道中被抛弃,这就意味着读进程最多只能有1个,否则可能会有读错数据的情况
消息传递
前言:进程间的数据交换以格式化消息为单位。进程通过操作系统提供的“发送消息/接收消息”两个原语进行数据交换
注意:一个格式化的消息会分为消息头和消息体两个部分
消息传递的方式
- 直接通信方式:消息直接挂在接收进程的消息缓冲队列上
- 间接通信方式:消息要先发送到中间体(信箱)中,因此也称“信箱通信方式”
直接通信方式
理解:每一个进程会有一个消息缓冲队列,若有另外一个进程想给该进程发送消息的时候,那么另外一个进程会先创建好格式化的消息体,然后这个消息会通过发送原语发送给该消息;然后这个消息就会挂到该进程消息缓冲队列的队尾,然后该进程会通过接收原语依次把队列中的这些消息一个个的取走进行处理
间接通信方式
理解:系统会为各个通信的进程管理一个信箱,这个信箱中可能会有各种各样的消息;并且这个消息可能是不同进程之间通信的一些消息;具体是由那个进程发,那个进程收这些都会包含在消息头里;若一个进程想给另一个进程发送消息,这个消息会用发送原语发送到中间实体信箱当中,之后读进程会用接收原语从信箱当中取走消息。
线程
何谓线程
前言:有的进程需要同时处理很多事情的,而传统的进程只能串行的执行一系列程序。为此,引入了线程来增加并发度
线程:线程是程序执行流的最小单位,它包含在进程之中,是进程的实际运作单位
注意:
- 传统的进程是程序执行流的最小单位,但是引入了线程之后,线程变成程序执行流的最小单位
- 在没有引入线程前,一个进程就对应一份代码,这些代码只能顺序的依次往下执行;但是引入线程后,每个进程可以有多个线程,并且这些线程可以有各自不同的代码,也可以是不同的线程运行的是同一份代码,但是这些代码都会并发的被CPU处理,并发的依次执行下去
- 线程是一个基本的CPU执行单元,也是程序执行流的最小单位。引入线程后,不仅进程之间可以并发,进程内的各个线程之间也可以并发,从而进一步提升了系统的并发度,使得一个进程内也可以并发处理各种任务(如QQ视频、文字聊天、传文件)
- 引入线程后进程只作为除了CPU之外的系统资源分配单位(如打印机、内存地址空间等都是分配给进程的)
- 一个进程可以开启多个线程,其中有一个主线程来调动本进程中的其他线程;我们看到的进程切换切换的也是不同进程的主线程
- 每个线程在共享同一个进程的内存空间的同时又有自己独立的内存空间
引入线程后的变化
线程属性
线程的实现方式
用户级线程
注意:
- 用户级别线程由应用程序通过线程库实现,所有的线程管理工作都由应用程序负责(包括线程的切换)
- 用户级线程中,线程的切换在用户态下即可完成,无需操作系统干预
- 在用户看来,是有多个线程。但是在操作系统内核看来,并意识不到线程的存在(用户级线程对用户不透明,对操作系统透明)
- 可以理解为用户级线程就是从用户视角能看到的线程
内核级线程
注意:
- 内核级线程的管理工作由操作系统内核完成。线程的调度、切换等工作都由内核负责,因此内核级线程的切换必然需要在核心态下才能完成
- 可以理解为内核级线程就是从操作系统视角能看到的线程(用户也可以看到)
重要:
- 在同时支持用户级线程进和内核级线程的操作系统中,可采用二者组合的方式:将n个用户级线程映射到m个内核级线程上(n>=m)
- 操作系统只看得到内核级线程,因此只有内核级线程才是处理机分配的单位
多线程模型
前言:在同时支持用户级线程和内核级线程的系统中,由几个用户级线程映射到几个内核级线程的问题引出了多线程模型的问题
多对一模型
含义:多个用户级线程映射到一个内核级线程。每个用户级进程只对应一个内核级线程
优缺点
- 优点:用户级线程由于其管理是由应用程序来负责的,所以用户级线程的切换只需要在用户态下即可完成,不需要切换到核心态,线程管理的系统开销下,效率高
- 缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞(内核级线程也被阻塞——因为在操作系统看来仅有一个线程,用户级线程阻塞导致内核级线程也阻塞),并发度不高。多个线程不可在多核处理机上并行运行
一对一模型
含义:一个用户级线程映射到一个内核级线程。每个用户进程有与用户级线程同数量的内核级线程
优缺点
- 优点:若某一个用户级线程被阻塞,那么其他的用户级线程还可以继续执行下去,并发能力强;同时多个用户级线程由于都各自映射到不同的内核级线程上,而内核级线程又是处理机调度的唯一单位,所以这些用户级线程可以在多核处理机下并行运行
- 缺点:一个用户进程会占用多个内核级线程,线程的切换由操作系统的内核来完成,需要切换到核心态,因此线程的管理成本高,开销大
多对多模型
含义:n个用户级线程映射到m个内核级线程(n>=m)每个用户进程对应m个内核级线程
优点:克服了多对一模型的并发度不高的缺点,又克服了一对一模型中一个用户进程占用太多内核级线程,开销太大的缺点
处理机调度
处理机调度的基本概念
调度:当有一堆任务要处理,但由于资源有限,有些事情没法同时处理。这就需要确定某种规则来决定处理这些任务的顺序,这就是“调度”研究的问题
处理机调度:在多道程序系统中,进程的数量往往是多于处理机个数的,这样不可能同时并行的处理各个进程。处理机调度就是从就绪队列中按照一定的算法选择一个进程并将处理机分配给它运行,以实现进程的并发执行
高级调度
前言:由于内存空间有限,有时无法将用户提交的作业全部放入内存,因此就需要确定某种规则来决定将作业调入内存的顺序
高级调度(作业调度):指按照一定的原则从外存上处于后背队列的作业中挑选一个(或多个)作业,给他们分配内存等必要资源,并建立相应的进程(建立PCB),以使他们获得竞争处理机的权利
注意:高级调度是辅存(外存)与内存之间的调度。每个作业只调入一次,只调出一次。作业调入时会建立相应的PCB,作业调出时会撤销PCB。高级调度主要是指调入的问题,因为只有调入的时机需要操作系统来确定,但调出的时机必然是作业运行结束才调出
中级调度
前言:引入虚拟存储技术之后,可以将暂时不能运行的进程调至外存等待。等他重新具备了运行条件且内存又稍有空闲的时候,再重新调入内存;这么做的目的是为了提高内存利用率和系统吞吐量
中级调度(内存调度):就是要决定将那个处于挂起状态的进程重新调入内存
注意:
- 暂时调到外存等待进程的状态为挂起状态。值得注意的是,PCB并不会一起调到外存,而是会常驻内存。PCB会记录进程数据在外存中的存放位置,进程状态等信息,操作系统通过内存中的PCB来保持对各个进程之间的监控、管理。被挂起的进程PCB会被放到挂起队列中
- 在中级调度中,一个进程可能被多次调入,多次调出内存,因此中级调度的发生频率要比高级调度更高
低级调度
低级调度(进程调度):其主要任务是按照某种方法和策略从就绪队列中选取一个进程,将处理机资源分配给他
注意:
- 低级调度是操作系统中最基本的一种调度,在一般的操作系统中都必须配置进程调度
- 进程调度的频率很高,一般几十毫秒一次
- 低级调度是内存与处理机之间的调度
三种调度的联系和对比
挂起状态与七状态模型
前言:暂时调到外存等待的进程状态为挂起状态,挂起状态又可以分为就绪挂起、阻塞挂起两种状态
就绪挂起:一个处于就绪状态的进程若此时这个系统的负载比较高,内存空间已经不够用了;那么他就有可能会把一个处于就绪态的进程暂时调到外存当中,此时该进程就进入了一个就绪挂起的状态;一直到内存空间空闲,或者该进程需要继续执行,那么这个进程将会被激活,把他相应的数据又会挪回内存,这样一个就绪挂起的进程又回到了就绪态
阻塞挂起:一个处于阻塞状态的进程也可以被阻塞,也可以重新的被调入内存,重新被激活回到阻塞态
注意:
- 有的操作系统有可能使阻塞挂起的进程,当他的阻塞事件发生的时候;这个进程就会直接进入到就绪挂起的状态
- 有的时候一个进程处于运行态,运行结束后可能直接被放到外存当中,让他进入到就绪挂起的状态
- 有的时候一个处于创建态的进程当他创建结束后,有可能出现内存空间不够的情况,这种情况有可能处于创建态的进程直接进入就绪挂起的状态
- 挂起和阻塞两种状态都是暂时不能获得CPU的服务,但是挂起状态是将进程映像调到外存去了,而阻塞状态下进程映像还在内存中
- 有的操作系统会把就绪挂起、阻塞挂起分为两个挂起队列,甚至会根据阻塞原因不同再把阻塞挂起进一步分为多个队列
进程调度
进程调度的时机
进程调度(作业调度):就是按照某种算法从就绪队列中选择一个进程为其分配处理机
进程调度与切换的情况
不能进行进程调度的情况
临界区与临界资源
- 临界资源:一个时间段内只允许一个进程使用的资源。各进程需要互斥的访问临界资源
- 临界区:访问临界资源的那段代码
进程调度的方式
- 非剥夺调度方式:又称非抢占式。即只允许进程主动放弃处理机,在运行过程中即便有更紧迫的任务到达,当前进程依然会继续使用处理机,直到该进程中止或主动要求进入阻塞态
- 剥夺调度方式:又称抢占式。当一个进程正在处理机上执行的时候,若有一个更重要更紧迫的进程需要使用处理机,则立即暂停正在执行的进程,将处理机分配给更重要更紧迫的那个进程
进程的切换
含义:一个进程让出处理机,由另一个进程占用处理及的过程
进程切换的过程
- 对原来进程的各种数据的保存
- 对新进程各种数据的恢复(如:程序计数器、程序状态字、各种数据寄存器等处理机现场信息,这些信息一般保存在进程控制块)
注意:进程切换是有代价的,因此过于频繁的进行进程的调度、切换,必然会使整个系统的效率降低,使系统大部分时间都花在进程切换上,而真正用于执行进程的时间减少。
调度算法的评价指标
CPU利用率
含义:是指CPU忙碌时间占总时间的比例
公式:CPU利用率=CPU忙碌时间/总时间
系统吞吐量
前言:对于计算机来说,希望能用尽可能少的时间处理完尽可能多的作业
系统吞吐量:单位时间内完成作业的数量
公式:系统吞吐量=总共完成作业的数量/总共花了多少时间
周转时间
前言:对于计算机来说,它很关心自己的作业从提交到完成花了多少时间
周转时间:是指从作业被提交给系统开始,到作业完成为止的这段时间间隔
公式:
- 周转时间=作业的完成时间-作业提交时间
- 平均周转时间=各作业周转时间之和/作业数
- 带权周转时间=作业周转时间/作业实际运行的时间
- 平均带权周转时间=各作业带权周转时间之和/作业数
注意:
- 带权周转时间必然>=1
- 带权周转时间与周转时间都是越小越好
- 带权周转时间越小,用户满意度越高
等待时间
含义:指进程/作业处于等待处理机状态的时间之和,等待时间越长,用户满意度越低
注意:
- 对于进程来说,等待时间就是指进程建立后等待被服务的时间之和,在等待IO完成期间其实进程也是在被服务的,所以不进入等待时间
- 对于作业来说,不仅要考虑建立进程后等待的时间,还要加上作业在外存后背队列中等待的时间
响应时间
含义:指用户从提出请求到首次产生响应所用的时间
调度算法
先来先服务算法(first come first serve)
短作业优先(shortest job first)
最短剩余时间优先算法:每当有进程加入到就绪队列改变时就需要调度,若新到达的进程剩余时间比当前运行的进程剩余时间更短,则由新进程抢占处理机,当前运行进程重新回到就绪队列。
注意:短作业优先调度算法为每次调度时选择当前已到达且运行时间最短的作业/进程
高响应比优先算法(Highest Response Ratio Next)
时间片轮转(Round-Robin)
时间片轮转算法:轮流让就绪队列中的进程依次执行一个时间片(每次选择的都是排在就绪队列队头的进程)
注意:若时间片太大,使得每个进程都可以在一个时间片内完成,则时间片轮转算法就会退化为先来先服务算法,并且会增大进程响应时间,因此时间片不能太大;另一方面,进程调度、切换是有时间代价的(保存、恢复运行环境)因此若时间片太小,会导致进程切换过于频繁,系统会花大量时间来处理进程切换,从而导致实际用于进程执行的时间比例减少。可见时间片也不能太小
优先级调度算法
抢占式优先级调度算法:每次调度时选择当前已经到达且优先级最高的进程。当前进程主动放弃处理机时发生调度。另外,当就绪队列发生变化时也需要检查是否会发生抢占
注意:
- 就绪队列未必只有1个,可以按照不同优先级来组织。另外,也可以把优先级最高的进程排在更靠近队头的位置
- 根据优先级是否可以动态改变,可将优先级分为静态优先级和动态优先级两种;
- 静态优先级:创建进程时确定,之后一直不变
- 动态优先级:创建进程时有一个初始值,之后会根据情况动态的调整优先级
- 通常系统进程优先级高于用户进程、前台进程优先级高于后台进程优先级、操作系统更偏好I/O繁忙型进程
多级反馈队列算法
过程:
- 设置多级就绪队列,各队列优先级从高到低,为各级队列分配的时间片由小到大
- 新进程到达时先进入一级队列,按FCFS原则排队等待被分配时间片。若用完时间片进程还未结束,则进程进入下一级队列队尾。若此时已经在最下级队列,则重新放回最下级队列队尾
- 只有第K级队列为空时,才会为k+1级队头的进程分配时间片
- 被抢占处理机的进程重新放回原队列队尾
算法总结
进程同步与互斥
概念
同步:同步亦称直接制约关系,他是指为了完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调他们的工作次序而产生的制约关系;进程间的直接制约关系就是源于他们之间的相互合作
进程互斥:对于临界资源的访问,必须互斥的进行。互斥,亦称间接制约关系。进程互斥指当一个进程访问某临界资源时,另一个要访问该临界资源的进程必须等待。当前访问临界资源的进程访问结束,释放资源之后,另一个进程才能去访问临界资源
对临界资源的互斥访问逻辑上可以分为如下四部分
- 进入区:负责检查是否可以进入临界区,若可以进入,则应设置正在访问临界资源的标识(可理解为上锁)以阻止其他进程同时进入临界区
- 临界区:访问临界资源的那段代码
- 退出区:负责解除正在访问临界资源的标志(可理解为解锁)
- 剩余区:做其他处理
为了实现对临界资源访问,同时保证整体性能,须遵循以下原则
- 空闲让进:临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区
- 忙则等待:当已有进程进入临界区时,其他试图进入临界区的进程必须等待
- 有限等待:对请求访问的进程,应保证能在有限的时间内进入临界区(保证不会饥饿)
- 让权等待:当进程不能进入临界区时,应当立即释放处理机,防止进程忙等待
进程互斥的软件实现方法
单标志法
算法思想:两个进程在访问临界区后会把使用临界区的权限转交给另一个进程。也就是说每个进程进入临界区的权限只能被另一个进程赋予(两个进程交替使用临界区)
理解:由上可知,turn=0表示开始只允许P0进程进入临界区,若P1进入则会导致一直while循环检查,直到P1的时间片用完后切换P0上场;P0进入临界区后访问完毕后才可以让P1上场(turn=1),如此循环往复;
问题:刚开始访问临界区的是P0,若P0进程一直不访问临界区的话,那么turn的值一直不变,P1就一直无法访问临界区;临界区空闲,不满足空闲让进
双标志检验法
算法思想:设置一个标志位flag[],数组中各元素用来标记各进程想进入临界区的意愿,比如“flag[0]=true”意味着0号进程p0现在想要进入临界区。每个进程在进入临界区之前先检验当前有没有别的进程想要进入临界区,若没有,则把自身对应的标志flag[i]设为true,之后开始访问临界区
理解:若P0想进入临界区,他先检查P1是否想进,P1不想进则它将自己的意愿改为想进后进入临界区;此时P1又想进了,那么检查P0是否想进,因为P0想进P1便一直循环检查,直到P0出临界区后将自己的意愿改为不想进后才可以进入临界区,如此循环往复
问题:若P0和P1一起检查对方想没想进入临界区(1526),那么发现对方都没想进;最终P0和P1会一起进入临界区(两个标志位都为true);违背忙则等待
双标志后检查法
算法思想:双标志先检查法的改版。前一个算法是先检查后上锁,但这两个操作又是无法一气呵成,因此导致了两个进程同时进入临界区的问题。因此,人们又想到先上锁,后检查的方法来避免上述问题
理解:P0想进入临界区,那么他先将自己的意愿改为想去,再检查P1是否想进,看见P1不想进,那么自己进,此时P1想进,那么先将自己的意愿改为想进后看见P0也想进,就会一直循环直到P0放锁,如此循环往复
问题:P0和P1均想进临界区(flag[0]=flag[1]=true)之后都开始检查,发现对方都想进临界区,但是谁也进不去只能干着急,违反空闲让进、有限等待
peterson算法
算法思想:双标志后检查法中,两个进程都争着想进入临界区,但是谁也不让谁,最后谁都无法进入临界区。peterson想到了一种方法,若双方都争着想进入临界区,那么可以让进程尝试孔融让梨,主动让对方先进入临界区
理解:P0想进临界区,但是他让P1进,然后他检查P1是否想进,看见P1不想进,那么自己就进去了;此时P1想进,但是他让P0进后看到P0想进,那么就会一直循环等待,直到P0进去完了修改自己的意愿改为不想进
分析并发:P0和P1都想进临界区,那么P0表示他让P1进入临界区;此时P0循环直到时间片用完后P1执行到7该执行8后发现P0也想进,同时自己也让P0进去了,然后就开始循环直到时间片用完,此时运行到P0了,由于P1谦让了(turn的值变为0);那么P0进程在进行while检查时发现P1让自己进,然后就进临界区了
进程互斥的硬件实现方法
中断屏蔽方法
含义:利用“开/关中断指令”实现(与原语的实现思想相同,即在某进程开始访问临界区到结束访问为止都不允许被中断,也就不能发生进程切换,因此也不可能发生两个同时访问临界区的情况)
优缺点
- 优点:简单、高效
- 缺点:不适用于多处理机;只适用于操作系统内核进程,不适用于用户进程(因为开关中断指令只能运行在内核态,这组指令若让用户随意使用则会很危险)
TestAndSet指令
含义:简称TS指令,有的地方也称TestAndSetLock指令或TLS指令
注意:TSL指令是用硬件指令实现的,执行的过程不允许被中断,只能一气呵成
理解:线程进入临界区前while循环检查是否被上锁,若上锁则一直循环等待,直到另一个进程放了锁
优缺点
- 优点:实现简单,无需像软件实现方法那样严格检查是否会有逻辑漏洞;适用于多处理机环境
- 缺点:不满足让权等待的原则,暂时无法进入临界区的进程会占用cpu并执行TLS指令,从而导致忙等。
Swap指令
前言:swap指令使用硬件实现的,执行过程中不允许被中断,只能一气呵成
注意:swap指令和TestAndSet指令类似(lock为false就是没锁,lock为true就是有锁,访问时lock=true,old=false——因为已经交换了,下一个进程想访问临界区看到old=lock=true就没法进去,除非上一个进程放锁)