操作系统期末复习版
第一章 操作系统概论
1.1 操作系统的资源管理功能和目标
操作系统的定义
操作系统的定义:OS(operating system)是管理系统资源、控制程序执行、改善人机界面、提供各种服务、合理组织计算机工作流程和为用户有效使用计算机提供良好运行环境的一直系统软件。
计算机系统的资源:
硬件:CPU、内存、外存、输入输出设备;
软件:程序和数据。
操作系统以系统功能调用的形式在内部提供了完成从输入设备输入数据的程序模块,该模块负责所有涉及硬件机械电子特性的处理。
在多任务系统中,需要有专门的处理机调度模块负责分配处理机和保护处理机现场,在进程间完成进程切换的工作。
操作系统回收用户进程所占用的内存等软硬件资源,进行结束处理。
操作系统的组成
操作系统在计算机系统中的位置
操作系统的资源管理技术
1.资源复用
资源复用是指多个进程共享物理资源,包括分割资源为较多更小单位的空分复用和分时轮流使用资源的时分复用。
进程是有资格获得系统资源的独立主体。
2.资源虚化
资源虚化利用一类事物模拟另外一类事物,造成另外一类事物数量更多或容量更大的假象。
3.资源抽象
资源抽象是利用软件封装复杂的硬件或软件设施,简化资源应用接口的一种资源管理技术。
操作系统的目标
1.方便用户使用;
2.扩充机器功能;
3.管理系统资源;
4.提高系统效率;
5.构筑开放环境。
1.2 操作系统的功能
处理器管理功能
1.进程控制和管理:包括进程创建、运行、阻塞、终止等;
2.进程同步和互斥;
3.进程通信和死锁;
4.线程控制和管理:线程的创建、运行、暂停、终止等;
5.处理器调度:分作业调度、中程调度、低级调度等。
存储管理功能
1.存储分配:为各个进程及操作系统自身分配所需内存空间,以及回收归还的内存空间。
2.存储共享:
3.地址转换与存储保护:
地址转换——将程序装入内存创建进程时,需将程序中的逻辑地址转变为物理地址。
存储保护——内存中的一个进程只能在自己的地址空间访问,不可以访问其他进程或者操作系统的地址空间。
4.存储扩充:通过虚拟存储器技术将内、外存统一起来,将外存的一部分作为容纳进程的辅助空间,使进程的存在空间得到扩充。
设备管理功能
1.设备分配:在多个进程直接分配共享设备,确保设备的高效利用、无死锁、无饥饿;
2.缓冲管理:缓冲区用来在设备与进程直接实现数据的批量传送;
3.设备驱动:设备驱动程序使设备硬件的一层抽象,用来向设备发送命令,与设备进行通信;
4.设备的独立性:实际上是程序的独立性,是程序独立于设备的属性。同一程序对多种不同设备均可适用;
5.实现虚拟设备:虚拟设备时利用一种设备模拟另一种设备的技术,目的是将独占设备改造为共享设备,将联机处理改造为批处理,以提高CPU与设备并行工作潜力,减少进程等待时间,提高进程运行效率。
文件管理功能
1.提供文件逻辑组织方法:文件内容的结构是字节流还是记录序列;
2.提供文件物理组织方法:文件以物理块为单位存储时,如何建立物理块之间的先后顺序,以反映文件内容之间的逻辑顺序;
3.提供文件的存取方法:文件顺序存取、随机存取还是索引存取;
4.提供文件的使用方法;
5.实现文件的目录管理:目录用于检索文件,其结构影响文件查找效率;
6.实现文件的存取控制:规定文件的许可访问者及允许各个访问者执行的文件访问操作类型,实现文件的安全访问;
7.实现文件的存储空间管理:对外存空闲空间进行管理,以便及时了解空闲空间的容量和位置,为文件存储空间的分配和回收建立必要的数据结构。
网络与通信管理功能
1.网上资源管理功能;
2.数据通信管理功能;
3.网络管理功能:故障管理、安全管理、性能管理、记账管理和配置管理。
1.3操作系统的主要特性
一、并发性
-
并发性:指两个或两个以上的事件或活动在同一时间间隔内发生;
-
并行性:指两个或两个以上的事件或活动在同一时刻发生。
操作系统的并发性是指计算机系统中同时存在若干个运行着的程序(包括操作系统程序和用户程序),这些程序交替、穿插地执行。
并发性的好处:程序并发执行能够驱动不同的部件同时工作,减少或消除部件和部件之间的相互等待,改善系统资源利用率,改进系统吞吐量,提高系统效率。
二、共享
共享:是指操作系统中的资源(包括硬件资源和信息资源)可被多个并发执行的进程共同使用,而不是被其中某一个程序所独占。
资源共享方式有两种:
-
互斥访问:也称顺序访问,系统中的某些资源同一时间内只允许一个进程访问,本质含义——共享资源的若干任务顺序使用资源,而不是交替、穿插地使用。(eg——打印机)
-
同时访问:也称并发访问,允许同一时间内多个进程对某些资源进行交替、穿插地并发访问,本质含义——共享资源的若干任务交替、穿插地使用资源。(eg——磁盘)
三、异步性
异步性也称随机性,在多道程序环境中,程序的执行不是一贯到底,而是“走走停停”,何时“走”,何时“停”是不可预知的。
四、虚拟性
虚拟性是操作系统资源管理技术的特性,虚拟资源管理技术即资源虚化,将物理上的一个实体变成逻辑上的多个对应物,或把物理上的多个实体变成逻辑上的一个对应物。
-
虚拟处理器:将一个物理处理器变成多个逻辑处理器;、
-
虚拟存储器:将内存和外存的一部分变成一个更大的逻辑内存;
-
虚拟设备:使用磁盘的一部分及管理软件将慢速的联机独占设备改造成为批处理虚拟共享设备;
-
虚拟文件系统:表征不同文件系统公告特征的抽象文件系统框架,达到一个操作系统支持多种不同的文件系统。
1.4 操作系统的发展和分类
一、人工操作阶段
略
二、管理程序阶段
管理程序阶段计算机操作特点:
-
作业控制语言代替机械操作;
-
脱机操作代替联机操作;
-
自动批处理作业。
三、多道程序设计和操作系统的形成
多道程序
-
概念:指允许多个程序同时进入一个计算机系统的主存储器并启动进行交替计算的方法。
-
硬件基础:中断以及通道技术。
-
好处:多道程序设计提高了CPU、内存和I/O设备的利用率,改进了系统吞吐率,发挥了系统的并行性,提高了效率。
-
道数:内存储器的容量、用户的响应时间和程序使用的资源类型等因数影响多道程序道数的多寡。
操作系统形成的标志:多道批处理操作系统、分时操作系统和实时操作系统的出现标志着操作系统正式形成。
四、操作系统的分类
1.批处理操作系统
2.分时操作系统
3.实时操作系统
4.通用操作系统
1.5 操作系统的内置接口
一、程序接口
1.程序接口的概念:程序接口又称为应用编程接口API,供程序员在编制程序时以程序语句或指令的形式调用操作系统的服务和功能。
程序接口由一组系统调用组成,系统调用是操作系统的组成部分,用于管理和控制系统中软硬件资源的共享使用。
2.系统调用的概念:系统调用是为了扩充机器功能、增强系统能力、方便用户使用而在内核中建立的过程(函数),它是用户程序或其它系统程序获得操作系统服务的唯一途径。
系统调用采用汇编语言或C语言来实现。
3.系统调用的分类
略
4.陷入或异常处理机制的概念
在操作系统中,实现系统调用功能的机制称为陷入或异常处理机制。
5.访管指令(陷入指令或异常中断指令)
由于系统调用而引起处理器中断的机器指令称为访管指令(陷入指令或异常中断指令)
6.系统调用处理过程
略
7.系统调用与过程(函数)调用的区别
(1)转移目标程序定位方式不同
-
过程(函数)使用一般调用指令,其转向地址包含在跳转语句中;
-
系统调用不包含处理程序入口,仅仅提供功能号,按功能号调用;
(2)被调用代码的位置不同
-
在过程(函数)调用中,调用程序和被调用代码在同一程序内,经过连接编译后作为目标代码的一部分,当过程(函数)升级或修改时,必须重新编译连接。
-
系统调用的处理代码在调用程序之外(在操作系统中),系统调用处理代码升级或修改时,与调用程序无关。
(3)转移目标程序提供者不同
-
过程(函数)由编译系统提供或用户编写,不同编译系统提供的过程(函数)不同;
-
系统调用由操作系统提供,一旦操作系统设计好,系统调用的功能、种类和数量就固定不变了。
(4)调用的实现不同
-
程序使用一般机器指令(跳转指令)来调用过程(函数),是在用户态运行的;
-
程序执行系统调用,是通过中断机构来实现的,需要从用户态转变到核心态,在管理态执行。
二、操作接口
1.操作接口的定义
操作接口又称为作业级接口,是操作系统为用户提供的操作控制计算机工作和提供服务手段的集合。
操作接口与程序接口的重要区别:
-
操作接口是非编译即可使用的;
-
程序接口需要经过编译方可使用。
2.操作接口的类型
(1)操作控制命令:由一组命令及命令解释程序组成,也称为命令接口或联机用户接口;
(2)批处理系统提供的作业控制语言:作业控制语言(JCL)由一组作业控制卡,或作业控制语句,或作业控制操作命令组成,也称为脱机用户接口。脱机用户可通过作业控制语言对作业进行脱机控制;
(3)图形用户界面:图形用户界面(GUI)使用窗口、图标、菜单和鼠标等技术,将系统的功能、各种应用程序和文件用图形符号直观、逼真地表示出来,用户可通过选择窗口、菜单、对话框和滚动条完成对他们的作业的各种控制和操作;
(4)新型用户界面等实现手段:虚拟现实接口、多感知用户接口、自然化用户接口、智能化用户接口技术的成熟将为操作系统应用带来更大的方便。
1.6 操作系统的结构设计
一、操作系统的主要构件
1.内核
操作系统内核是对硬件进行首次抽象的一层软件,也称为硬件抽象层,用于隐藏硬件复杂性,为上层软件提供简洁、统一的硬件无关的接口。
2.进程
进程是程序的一次运行过程,用于完成特定任务。
3.线程
线程是进程中的一个执行流,一个进程可以包含多个执行流,每个执行流分别承担一个计算任务。
4.管程
管程是用来管理共享资源的一种对象。管程封装了对共享资源进行同步、互斥操作的数据结构和一组过程。
二、操作系统的结构
1.单体式结构
操作系统由过程集合构成,链接成一个大型可执行二进制程序。
2.层次式结构
层次式结构是把操作系统划分为内核和若干模块(或进程),这些模块(或进程)按功能的调用次序排列成若干层次,各层之间只能是单向依赖或单向调用关系,即低层为高层服务,高层可以调用低层的功能。
3.客户机/服务器与微内核结构
客户机/服务器与微内核结构将操作系统分成两大部分,一部分是运行在用户态并以客户机/服务器方式活动的进程;另一部分是运行在核心态的内核。除内核部分外,操作系统的其他部分被分成若干个相对独立的进程。
三、操作系统运行模型
1.操作系统运行模型与内核结构之间的关系
操作系统内核结构与运行模型之间的对应关系是近似的,不是绝对的。
2.非进程模式(内核模块调用模式)
以非进程模式运行的操作系统,其功能组织成一组例行程序,操作系统服务例程以系统调用的形式与用户进程代码结合在一起执行,构成形式上的单一进程。这种模式也称为内核模块调用模式或系统调用模式。
3.进程模式
进程模式将操作系统组织成一组系统进程,即操作系统功能是这些系统进程集合运行的结果,这些系统进程也称为服务器或服务器进程,它们与用户进程或其他服务器进程之间构成了客户机/服务器关系。
第二章 处理器管理
2.1处理器
一、寄存器
寄存器与操作系统的关系——处理器现场管理
处理器属于分时复用型的共享资源,其中的寄存器被操作系统和各个进程所共享,任意瞬时的寄存器内容构成处理器工作现场。
当进程或任务发生切换时,寄存器内容必须被保存,以便进程或任务恢复执行时,还原处理器工作现场。
寄存器分类:
-
数据类:存放操作数或计算结果:通用寄存器、段寄存器;
-
地址类:存放要访问的内存地址或设备I/O地址:通用寄存器、段寄存器、系统地址寄存器、指令指针寄存器;
-
控制类:存放处理器的控制和状态信息:标志寄存器、控制寄存器。
二、指令系统、特权指令与非特权指令
指令分类:
-
数据传输类:完成处理器与存储器之间、处理器与I/O设备之间的数据传送操作;
-
数据处理类:完成运算器对数据的算术操作、逻辑操作等计算功能;
-
控制类指令:改变指令执行顺序以及控制资源的使用权限。
特权指令与非特权指令:
操作系统执行非特权指令与特权指令,其中操作系统通过执行特权指令来协调管理共享资源(软件与硬件)来控制计算机系统;
普通用户程序执行非特权指令
三、处理器状态及切换
1、处理器状态(处理器运行模式)分类:
-
管理状态:程序可以执行全部指令,访问硬件等共享资源的所有功能;
-
用户状态:程序只能执行非特权指令,访问资源功能的子集。
两种状态可以相互转换。
2、实际处理器的状态(运行模式)数目
-
0级:操作系统内核级:处理I/O、存储管理和其他关键操作;
-
1级:系统调用处理程序级:程序只能执行非特权指令;
-
2级:共享库过程级:可以被很多正在运行的程序共享,用户程序可以调用这些过程,读取它们的数据,但是不能修改它们;
-
3级:用户程序级:受到的保护最少。
Intel Pentium处理器状态(保护级别)的工作原理:
程序本身的保护级别限制了它所能够执行的指令集;限制了它所能调用的其它过程集。
3.处理器状态之际的转换:
(1)用户状态向管理状态的转换:
-
情况一:执行系统调用,请求操作系统服务;
-
情况二:中断事件产生,运行程序被中断,操作系统接管处理器,中断处理程序开始工作。
(2)管理状态向用户状态的转换:
执行加载程序状态字LPSW(Load PSW)指令,处理器由执行操作系统指令的管态切换为执行用户程序的用户态。
Intel Pentium提供的中断返回指令为IRET。
四、程序状态字寄存器
1、程序状态字寄存器⎯处理器工作状态的记录者:
-
处理器的工作状态记录在程序状态字(PSW)寄存器中;
-
每个正在执行的程序都有一个与其执行相关的PSW;
-
每个处理器都设置一个程序状态字寄存器。
2、程序状态字寄存器的主要内容:
-
程序基本状态:程序计数器、处理器状态位、条件码;
-
中断码:记录发生的中断事件;
-
中断屏蔽位:决定是否响应中断事件。
3、Intel Pentium程序状态字寄存器的组成:
(1)标志寄存器EFLAGS:
-
状态标志:符号、结果为零、溢出、进位、辅助进位、奇偶检验;
-
控制标志:串指令操作方向、虚拟86方式、步进、陷阱;
-
系统标志:I/O特权级、恢复、嵌套任务。
(2)指令指针寄存器EIP。
2.2中断
一、中断概念
中断:中断是指程序执行过程中,当发生某个事件时,中止CPU上现行程序的运行,引出处理该事件的程序执行的过程。
中断的重要用途:中断是改变指令执行流程、实现操作系统并发多任务功能的重要硬件机构,也是操作系统实现计算机控制的重要途径。
检测中断的时机:在每两条指令或某些特殊指令执行期间。
中断源:中断源是引起中断的事件。
中断装置:中断装置是发现中断源并产生中断的硬件。
中断机制的重要特征:当中断事件发生后,它能改变处理器内操作执行的顺序。
二、中断源分类
1、从中断事件的性质和激活的手段进行分类
强迫性中断事件
强迫性中断事件不是正在运行的程序所期待的,而是由于随机发生的某种事故或外部请求信号所引起的。
正在运行的程序不可预知强迫性中断事件发生的时机。
自愿性中断事件
自愿性中断事件是正在运行的程序所期待的事件。
这种事件由程序执行访管指令而引发,表示用户进程请求操作系统服务。
2、按照中断信号的来源对中断源分类
外中断:外中断是指来自处理器和主存之外的中断
内中断:内中断是指来自处理器和主存内部的中断
中断和异常的区别
对于正在执行的程序(进程)来说,异常是现行程序引发的,引发的原因是请求操作系统提供服务或者发生了意外错误;
中断不是现行程序引发的,而是由其它资源主体发出的,中断处理程序提供的服务一般不是现行程序需要的。
3、硬中断与软中断
硬中断:由硬件设施产生的中断信号,硬中断发生时会立刻响应。
软中断:利用软件模拟产生的中断信号,用于实现内核与进程或进程与进程之间的通信;接收软中断的进程运行时才能响应。
三、中断处理
1、硬件中断装置:
-
中断逻辑线路:发现中断源,产生中断信号;
-
中断寄存器:记录中断事件,其内容称中断字,中断字的每一位对应一个中断事件;
处理过程:发现中断源,响应中断请求然后保存现场,启动中断处理程序。
硬件中断装置处理过程实例——设备I/O操作完成后中断装置的典型操作。
2、软件中断处理程序
-
保护硬件未保护的处理状态;
-
识别各个中断源,分析中断原因;
-
处理发生的中断事件;
-
中断返回。
中断为操作系统控制计算机系统提供了机会。
中断使得处理器在进程和操作系统之间频繁的来回切换,但是处理器的控制权掌握在操作系统手中,而不是进程手中。
中断也提供了任务切换的机会。
一个问题:在系统中没有任何进程运行时,操作系统在干什么?系统会静止吗?
答:操作系统一直等待服务程序,并且会有时钟中断处理程序运行。
中断也像刹车,可以使用户程序及系统程序适时停止运行,以便重新分配系统资源,尤其是处理器资源,避免某些程序过长时间地垄断系统资源,破坏系统资源使用的公平性。中断犹如计算机系统的心脏,无论何时不能停止跳动,否则,计算机系统将失去驱动力。
2.3进程及其实现
一、引入进程概念的必要性
进程与程序是两个不同的概念。
进程与程序都包含程序,但是程序是静态的,进程是动态的,进程是按照程序运行的过程。同一个程序在一段时间内可以同时存在多个执行活动(即进程)分别对不同的数据进行处理。
对比考虑:按照图纸建造房屋和按照程序执行进程(任务)类似。
图纸对应程序,建造房屋对应执行进程,图纸与建造房屋很容易区别,但程序与程序的运行(进程)就不容易区别。
进程与程序容易混淆的原因总结:
-
两者主体内容几乎完全相同,程序与进程的主体几乎完全由相同的指令代码及数据空间组成,进程的指令代码及数据空间派生自程序;
-
两者在相同的介质上存在或活动,共存于计算机系统中,均可存放在外存和内存上。
二、进程定义和属性
1、进程的概念:
进程——进程是一个可并发执行的具有独立功能的程序关于某个数据集合的一次执行过程,也是操作系统进行资源分配和保护的基本单位。
进程:程序、数据、管理结构。
2、进程的属性
(1)结构性:进程控制块、程序块、数据块。
(2)共享性——同一程序运行于不同数据集合上构成不同的进程。
(3)动态性:进程具有生存期,进程因创建而产生,因调度而运行,因终止而撤销。进程的内容(主要是数据)是动态的,随着指令的执行而变化;程序的内容是固定的。
(4)独立性:进程是系统中资源分配和保护的基本单位,也是系统调度的独立单位。 合法的用户程序段应该属于某个进程,脱离任何进程的非操作系统程序段不被操作系统所感知,因而也无法作为资源分配和保护的单位以及处理器调度的单位。
(5)制约性:并发进程之间存在同步、互斥关系; 同步:存在协作关系的一个进程在某些执行点需要等待另一个进程发来的同步信号; 互斥:共享某些资源的进程需要依次排队使用这些资源。
(6)并发性:在单处理器系统环境下,各个进程轮流占用处理器,即交替、穿插使用处理器。
为什么要对进程划分状态?
答:系统中可以有非常多的进程,每个进程的执行都是走走停停,不是一贯到底的。进程至少可以划分“走”和“停”两大类状态。“停”的状态又可根据“停”的原因细分。划分进程状态对于简洁、条理地分类管理进程、合理调度系统资源非常必要。
三、进程状态与切换
1、三态模型
-
就绪态:等待系统分配处理器以便运行;(进程创建后,就处于就绪状态)
-
运行态:进程占有处理器正在运行;
-
等待态:进程不具备运行条件,正在等待某个事件完成。
2、五态模型
新建态(进程刚被创建,尚未提交参加处理器竞争)、就绪态、运行态、等待态、终止态(进程已经终止,但是进程尚未退出主存)。
3、七态模型
挂起——将进程从内存对换到外存,暂不参与进程调度,起到平滑系统负荷的目的。
新建态、就绪态、挂起就绪态、等待态、挂起等待态、运行态终止态。
引起进程挂起的主要原因:
(1)系统中的进程均处于等待状态;
(2)系统负荷过重;
(3)用户或者父进程挂起自己创建的进程,以便调试、检查和改正;
(4)操作系统挂起进程,以便检查资源使用情况,或者排除故障。
引起进程状态转换的具体原因:
-
等待态 -> 挂起等待态 :当前不存在就绪进程;
-
挂起等待态 -> 挂起就绪态 :进程等待事件结束;
-
挂起就绪态 ->就绪态 :内存没有就绪进程,挂起就绪态进程优先级高于就绪态进程;
-
就绪态 ->挂起就绪态 :减轻系统负荷;
-
挂起等待态 ->等待态 :内存空间充足,某个挂起等待态进程优先级较高,使该进程阻塞的事件即将结束;
-
运行态 ->挂起就绪态 :一个高优先级挂起等待进程的等待事件结束,它将抢占CPU,而此时主存不够
-
新建态 ->挂起就绪态 :系统资源承载负荷条件不适合立即接受新建进程
挂起进程的特征:
-
挂起进程不能立即被执行;
-
进程的挂起者可以是操作系统、父进程或进程自身;
-
结束进程挂起状态的命令只能由操作系统或父进程发出;
-
挂起进程所等待的事件独立于挂起条件,事件结束并不能导致进程具备执行条件。
四、进程描述
1、操作系统的控制结构:操作系统的控制结构是控制进程、管理系统资源的数据结构,同样类型的数据结构组成表,称为控制表。
2、进程实体(进程映像)的组成
进程控制块(PCB):操作系统跟踪、管理进程;
程序块、数据块、核心快三者定义进程的行为和功能,进程运行在核心态下时跟踪过程调用和过程间参数传递信息。
进程控制块(PCB):
-
每一个进程都捆绑一个进程控制块;
-
用途——标志信息、现场信息、控制信息;
-
创建和撤销时机:进程创建时建立进程控制块,进程撤销时回收进程控制块,进程控制块与进程一一对应。
进程程序块:
-
即被执行的程序,规定了进程一次运行应完成的功能。 程序块通常是纯代码,可被多个进程共享。
-
纯代码:在执行时本身不会发生改变的程序,这样的程序可被多个程序同时调用。调用它的所有程序需自备工作区。
进程数据块:
-
进程数据块是进程的私有地址空间,是程序运行时加工处理的对象。
-
全局变量、局部变量、常量、用户栈——进程专用。
进程核心栈:
-
每一个进程都将捆绑一个核心栈,进程在核心态工作时使用。
-
包括:中断/异常现场和函数调用的参数和返回地址。
【进程实体的内容随着进程的执行不断发生变化,某时刻进程实体的内容及其状态集合称为进程映像。】
3、进程上下文
进程上下文(context)⎯进程物理实体(进程控制块、程序块、数据块)和支持进程运行的环境(核心栈、用户栈、寄存器)合称为进程上下文。
4、进程控制块
用途:
-
记录和刻划进程状态及有关信息的数据结构
-
掌握进程的唯一资料结构
-
控制和管理进程的主要依据
-
是进程存在的唯一标识
-
每个进程都有且只有一个进程控制块
-
包括进程执行时的情况,以及进程让出处理器后所处的状态、断点等信息。
进程控制块包含的信息:
-
标识信息:外部标识符(类似于人的姓名)、内部标识符(类似于人的身份证号);
-
处理器现场信息:进程中断时用于保存处理器现场信息,进程恢复运行时从中恢复处理器现场,包括通用寄存器内容、控制寄存器内容、栈指针;
-
控制信息:用于管理和调度进程,包括进程调度信息、进程组成信息、进程间通信信息、进程在辅存的地址信息、CPU资源的占用和使用信息、进程特权信息、资源清单;
进程控制块的使用权和修改权
进程控制块的使用权和修改权属于操作系统程序,包括:调度程序、资源分配程序、中断处理程序、性能监视和分析程序。
5、进程队列及其管理 处于同一状态的所有PCB链接在一起的数据结构称为进程队列。 进程队列排队原则: 同一状态进程的PCB按先来先到、优先数或其它原则排成队列; 等待态进程队列按照等待原因细分为多个队列。
五、进程切换
进程切换即中断一个进程的执行转而执行另一个进程。
进程切换时系统需要完成的处理工作:
需要完成进程上下文切换,即保存被中断进程上下文到其进程控制块中,然后装入新进程上下文,使其从上次断点恢复执行,或者调度一个新的进程。
1、允许发生进程上下文切换的4种情况;
(1)当进程进入等待态时;等待了就把处理器等资源让出来去一边等待,别占着资源等待,进程切换由此发生。
(2)当进程完成其系统调用返回用户态,但不是最有资格获得CPU时;既然一个进程不是最有资格获得CPU的进程,那么就把处理器分配给最有资格获得它的进程,进程切换由此发生。
(3)当内核完成中断处理,进程返回用户态但不是最有资格获得CPU时;(情况分析类似于(2))
(4)当进程执行结束时。既然进程执行结束了,不再需要处理器等资源了,这些资源理应分配其它需要的进程,进程切换(包含进程创建)由此发生。
2、Linux进程调度时机
(1)进程状态转换的时刻,有权修改进程状态的主体是操作系统(进程控制块访问修改程序)所以,进程状态转换时,操作系统正在控制处理器,处理器一定处于核心态.
(2)当前进程的时间片用完时,进程由运行态转换为就绪态这是进程状态转换的时刻,是 Linux进程调度时机。
(3)设备驱动程序执行时,操作系统正在控制处理器,处理器一定处于核心态;
(4)进程从中断、异常或系统调用将要返回用户态时
六、模式切换
模式切换:CPU模式切换即处理器管态(核心态)与目态(用户态)之间的切换。
七、进程控制与管理
进程控制: 进程创建、进程阻塞、进程唤醒、进程挂起、进程激活、进程终止、进程撤销。这些控制和管理功能由操作系统中的原语实现。
原语:原语是在管态下执行、完成系统特定功能的不可中断的过程,具有原子操作性。 原语的执行不可中断原语的执行是顺序的而不可能是并发的。
原语的实现方法及其与系统调用的区别 原语可以采用屏蔽中断的系统调用来实现,以保证原语操作不被打断的特性。 即原语和系统调用都使用访管指令实现,具有相同的调用形式。 但普通系统调用可以被中断,原语不可中断。
1、进程的创建 进程创建的事件来源
-
提交一个批处理作业;
-
交互式作业登录;
-
操作系统创建一个服务进程;
-
存在的进程(父进程)创建(孵化)新的进程(子进程)。
2、进程的阻塞和唤醒 进程阻塞 进程阻塞是指一个进程让出处理器,去等待一个事件。
进程阻塞的步骤:
①停止进程执行,保存现场信息到PCB ②修改PCB的有关内容,如进程状态由运行改为等待,并把修改状态后的PCB加入相应等待队列 ③转入进程调度程序调度其他进程运行
进程唤醒的步骤 ①从相应等待队列中移出进程 ②修改进程PCB有关信息,如进程状态改为就绪并把修改PCB后的进程加入就绪队列 ③若被唤醒进程优先级高于当前运行进程,则重新设置调度标志
3.进程的撤销
撤销的主要原因:
-
进程正常运行结束
-
进程执行了非法指令、在常态下执行了特权指令
-
进程运行时间或等待时间超越了最大限定值
-
进程申请的内存超过最大限定值
-
越界错误、算术错误、严重的输入输出错误
-
操作员或操作系统干预
-
父进程撤销其子进程、父进程撤销、操作系 统终止
撤销的步骤:
①根据撤销进程标识号,从相应队列找到它 的PCB
②将该进程拥有的资源归还给父进程或操作 系统
③若该进程拥有子进程,则先撤销它的所有 子孙进程,以防它们脱离控制
④撤销进程出队,将它的PCB归还到PCB池
4、进程的挂起和激活 挂起原语执行过程
检查要被挂起进程的状态,若处于活动就绪态就修改为挂起就绪态,若处于阻塞态,则修改为挂起阻塞态。
被挂起进程PCB的非常驻部分、程序块、数据块要交换到磁盘对换区。
激活原语主要处理过程
-
把进程PCB非常驻部分、程序块、数据块调进内存,修改它的状态,挂起等待态改为等待态,挂起就绪态改为就绪态,加入相应队列中。
-
挂起原语既可由进程自己也可由其他进程调用,但激活原语只能由其它进程调用。
2.4线程及其实现
一、多线程的引入
计算成本、计算效率原因驱使
有时需要把分布在不同进程中、由不同进程承担的任务(即多进程任务)整合到一个进程中,把运行在多个进程中的并发任务转变为运行在同一个进程中的并发任务(即多线程任务),这样能够降低计算成本、提高计 算效率。
线程概念的引入——任务分解整合的结果
-
运行在同一个进程中的各个并发任务称为该进程的线程。
-
每个线程分别是进程中的一个执行流。
-
线程代表从进程划分出来的更小的任务单元。
-
在多线程进程中,进程是系统进行资源分配的基本单位,线程是处理器调度的基本单位。
传统进程的特征
-
传统进程中只有一个执行流,属于单线程进程,进程所代表的任务仅由一个执行流承担。
-
在单线程进程中,进程既是系统进行资源分配的基本单位,也是处理器调度的基本单位,两者合二为一。
【多进程任务向多线程任务的演变——任务整合】
【单线程进程任务向多线程任务的演变⎯任务分解】
二、多线程环境中的进程与线程
1、多线程环境中的进程
在多线程环境中,进程被定义为资源分配和保护的单位,多线程进程不再作为处理器调度和分派的基本单位,线程不是资源分配和保护的基本单位,而是处理器调度和分派的单位。
2、多线程环境中的线程
线程是进程中能够独立执行的实体(控制流),是处理器调度和分派的基本单位。
线程实体包括
-
线程控制块(TCB)
-
程序块
-
数据块
-
核心栈
3、线程的状态及进程级状态
线程的关键状态有:允许、就绪、阻塞
进程级状态:挂起
线程状态与进程状态之间的某些关系:
进程挂起——线程挂起 进程终止——线程终止 线程阻塞——(可能)进程阻塞、进程不阻塞
4、线程的控制 (1)创建 进程创建时系统会缺省创建并启动一个线程
已经启动的线程可以再创建和启动同一进程中的其它线程。 (2)阻塞:即等待,暂停线程执行;
(3)恢复:被阻塞线程等待的事件发生时,线程变成就绪态或相应状态;
(4)结束:线程终止,撤销线程。
5、并发多线程程序设计的优点
(1)切换速度快、切换开销小
(2)易于实现任务间的通信协作
(3)提高并发度
三、多线程实现方法
1、用户级线程
(1)用户级线程实现原理
用户级线程是在一个进程内部实现了类似进程调度、进程切换功能的一层进程内多任务应用支持软件。
用户级线程不是由操作系统提供的,因而,操作系统不参与用户级线程的调度。
(2)用户级线程的优点
①线程切换不需要内核特权方式
②针对不同进程按需选择不同的线程调度算法
③用户级线程可以运行在任何操作系统上,不需对内核做任何改造
(3)用户级线程的缺点
①线程执行系统调用时,不仅该线程被阻塞,且进程内的所有线程均被阻塞。
②纯用户级线程不能利用多处理器技术
2、内核级线程
(1)内核级线程实现原理
内核级线程是在操作系统内核层对进程实现的多线程功能,操作系统以线程作为处理器调度和分派的基本单位。
(2)内核级线程主要优点
①内核可以同时把同一进程中的多个线程调度到多个处理器上并行执行;
②进程中的一个线程被阻塞了,内核能调度同一进程的其它就绪线程运行;
③内核线程数据结构和堆栈小,切换速度快,内核自身也可采用多线程技术实现,提高系统执行速度和效率。
3、混合式线程
某些操作系统提供了同时支持用户级线程与内核级线程的混合式线程设施,线程的创建、调度和同步在用户空间进行。
一个应用程序中的多个用户级线程被映射到一些(小于或等于用户级线程的数目)内核级线程上。
2.5处理器调度系统
CPU 调度
-
操作系统需要合理安排系统中多个进程的执行顺序,使其轮换占用CPU资源,保证其并发性;
-
当系统中只有一个CPU时,只有一个进程会处于执行状态,而其它待运行进程则处于就绪状态。操作系统在必要的时候会中断当前进程的执行,并选择就绪状态中的一个进程让其占用CPU,这个过程被称为CPU调度(也叫进程调度);
-
完成选择进程任务的程序被称为 调度程序( Scheduler ) 。 调 度 程 序 根 据 调 度 策 略(Scheduling Policy)来决定在什么时候以什么样的方式选择一个新进程占用CPU;
-
当系统中拥有多个CPU或多核CPU时,调度程序还要考虑多(核)CPU之间的数据共享和数据同步。
三级调度
从系统接收到运行结束退出系统为止,作业可能要经历三级调度过程,即:高级调度、中间调度、低级调度。
一、高级调度
-
高级调度从磁盘后备作业队列中挑选若干作业进入内存,为其分配资源,创建进程;作业完成后还要做善后处理工作。
-
高级调度根据CPU空闲时间控制多道程序的道数,每当作业结束后,补充装入新的作业到内存。
-
高级调度配置在批处理系统或者操作系统的批处理部分中。
二、中间调度
-
中级调度决定哪些进程参与竞争处理器资源,途径是把一些进程换出主存,使之进入“挂起”状态,不参与进程调度;或者将进程对换到内存,解除挂起状态。
-
中级调度起到平滑和调整系统负荷的作用,提高主存利用率和系统吐吞率。
三、低级调度
-
低级调度的主要功能是按照某种原则决定就绪队列中的哪个进程或内核级线程获得处理器,并将处理器出让给它进行工作。
-
低级调度程序是操作系统最为核心的部分,执行十分频繁。
-
低级调度策略的优劣直接影响到整个系统的性能。
-
中断是执行低级调度的时机。
-
三级调度配置情况 低级调度是各类操作系统必须具有的功能;
-
在纯粹的分时或实时操作系统中,通常不需要配备高级调度,而仅配置低级调度;
-
一般的操作系统都配置高级调度和低级调度;
-
引进中级调度有利于提高主存利用率和作业吞吐量。
四、选择调度算法的原则
-
(1)资源利用率
-
(2)吞吐率
-
(3)公平性
-
(4)响应时间
-
(5)周转时间
(1)资源利用率
CPU利用率 = CPU有效工作时间/ CPU总的运行时间
CPU总的运行时间 = CPU有效工作时间 + CPU空闲等待时间
(2)吞吐率
吞吐率是单位时间内CPU处理的作业数
(3)公平性
调度算法要确保每个用户每个进程获得合理的CPU份额或其他资源份额,不会出现饥饿现象。
(4)响应时间
交互式进程从提交一个请求到接收到响应之间的时间间隔称为响应时间。
响应时间 = 命令传输到CPU的时间 + CPU处理命令的时间 + 处理结果返回终端的时间
(5)周转时间
批处理用户从作业提交给系统开始,到作业完成为止的时间间隔称为作业周转时间。
周转时间 = 作业在后备队列等待时间 + 作业进程在就绪队列等待时间 + 进程在CPU上运行时间 + 等待事件(在等待队列)时间
周转时间
设作业i提交给系统的时刻是t1,完成时刻是t2,则该作业的周转时间为:t1 = t2 - t1;
平均周转时间 n个作业的平均周转时间为:T = (Σti) / n
带权周转时间 若作业i的周转时间为ti,所需运行时间为tk,则作业i的带权周转时间为:wi=ti / tk
平均带权周转时间 平均作业带权周转时间为:W = (Σwi) / n
五、操作系统中的任务调度单位⎯作业、进程和线程
任务单位 作业、进程和线程是操作系统中不同级别的任务单位。
作业和作业步 作业对应一个完整的业务处理过程,该过程包含若干个相对独立又相互关联的顺序加工步骤,每个加工步骤称为一个作业步。
进程或线程对应一个作业步的处理过程。
【作业分解为许多进程,进程又分解为许多线程】
六、批处理作业的组织和管理
(1)批处理作业的组成结构
批处理作业被放到输入井,然后成批执行。
作业实体结构为:作业控制块(JCB)、程序、数据、作业说明书。其中作业说明书是指按规定格式书写的一个文件,描述用户对系统的各种请求和对作业的控制要求,与程序和数据一起提交给系统(管理员).
(2)批处理作业的创建
多道批处理操作系统的作业管理模块为每一个作业建立作业控制块(JCB)。批作业进入系统时,Spooling系统建立JCB,它是作业存在于系统的标志,作业撤离时,JCB也被撤销。
作业控制块的内容:
①作业情况(用户名、作业名、语言名)
②资源需求(估计CPU运行时间、最迟截止期、主存量、设备类型/台数、文件数和数据量、函数库/实用程序等)
③资源使用情况(进入系统时间、开始运行时间、己运行时间),作业控制(优先数、控制方式、操作顺序、出错处理等)、作业类型(CPU繁忙型、I/O繁忙型、批量 型、终端型)等信息。
(3)批处理作业的调度
①选择作业 根据资源状况和多道程序道数选择
②分配资源 分配内存、设备
③创建进程 进程调度程序为作业进程分配处理器
④作业控制 Spooling根据作业控制块和作业控制说明书控制作业的启动、作业步转接、程序调入、数据I/O、异常处理。
⑤后续处理 作业正常结束或出错终止时,作业调度程序回收资源、撤销作业控制块,并选择新作业进入主存
七、交互型作业的组织和管理
操作系统启动时,为连接至系统的每个终端创建一个终端进程,该进程接收用户输入的交互型命令、解释和执行命令。
用户输入退出命令则结束本次上机过程。
2.6处理器调度算法
一、低级调度的主要功能
处理器调度算法的功能
处理器调度算法是对一批进程或者线程确定处理器分配顺序的方法,即在众多进程或者线程中,当前选择哪个进程或者线程运行
处理器调度算法:
-
作业调度算法
-
中级调度算法
-
低级调度算法
调度 :调度实现进程/线程选择算法,选中者获得处理器。
分派:分派实现处理器的分配和绑定工作,将处理器分配给被选中的进程或线程,处理进程或线程上下文交换细节。
二、调度机制的逻辑功能模块
1、队列管理程序
进程/线程状态变化时,该进程/线程被加入不同队列。
2、上下文切换程序
负责进程/线程上下文切换。
3、调度程序
从就绪队列中选择下个运行的进程/线程。
三、低级调度的基本类型
1、剥夺方式
【剥夺是有条件执行下去,但被迫放弃处理器】
高优先级剥夺原则和时间片剥夺原则
2、非剥夺方式
【非剥夺是因自身原因无法执行下去,主动放弃处理器】
一旦某个进程或线程开始执行便不再出让处理器,除非该进程或线程运行结束或发生了某个事件不能继续执行。
剥夺和非剥夺调度各自适用的资源
剥夺调度方式——进程/线程的处理器
非剥夺方式——I/O设备等慢速资源
四、作业调度和低级调度算法
1、先来先服务算法(FCFS)
按照等待资源的先后顺序作为作业调度顺序的算法。
2、最短作业优先算法(SJF)
最短作业优先算法选取等待CPU的作业中估计计算时间最短的作业投入运行
3、最短剩余时间优先算法(SRTF)
最短剩余时间优先算法是剥夺式的最短时间优先调度算法。
如果新作业需要的CPU时间比当前正在执行的作业剩余所需CPU时间短,新作业将抢占当前作业的处理器。
4、响应比最高者优先算法(HRRF)
响应比最高者优先算法选择等待时间长且需要CPU时间短的作业优先调度,非剥夺调度
响应比 = 作业的响应时间/作业处理时间 = 1 + 已等待时间/作业处理时间
作业处理时间由用户给出,是一个常量
5、优先级调度算法
先级调度算法根据确定的优先级选取进程/线程,每次总是选择就绪队列中优先级最高者运行。
用户进程/线程优先级的规定者有两种:
(1)用户 用户自己提出优先级,称为外部指定法。优先级越高,费用越高。 (2)系统
由系统综合考虑有关因素来确定用户进程/线程的优先级,称为内部指定法。
根据优先级是否随时间而变,进程/线程优先级的确定有静态和动态两种方式。
(1)静态优先级在进程/线程创建时确定,此后不再改变。
(2)动态优先级随时间而变,基本原则是:
①正在运行的进程/线程随着占有CPU时间的增加优先级逐渐降低;
②就绪队列中等待CPU的进程/线程随着等待时间增加优先级逐渐提高。
6、轮转调度算法
(1)算法思想
调度程序每次把CPU分配给就绪队列首进程/线程使用一个时间间隔(称为时间片),就绪队列中的每个进程/线程轮流运行一个时间片。
(2)实现原理
实现轮转调度要使用一个间隔时钟。当一个进程开始运行时,将时间片的值置入间隔时钟内,当发生间隔时钟中断时,中断处理程序就通知处理器调度程序切换处理器。
(3)常用轮转法
最常用的轮转法是等时间片轮转法,每个进程轮流运行相同时间片。
改进的轮转法对于不同的进程分配不同的时间片,时间片的长短可以动态修改。
(4)时间片的选取
时间片大小的确定要从进程个数、切换开销、系统效率和响应时间等方面考虑。
7、多级反馈队列调度算法(反馈循环队列或多队列策略)
建立两个或多个就绪进程队列,每个队列赋予不同优先级,较高优先级队列一般分配给较短的时间片。
处理器调度每次先从高优先级就绪队列中选取可占有处理器的进程,只有在选不到时,才从较低优先级就绪队列中选取进程。
同一队列中的进程按先来先服务原则排队。
第三章 并发进程的同步、互斥与死锁
3.1 并发进程
一、程序执行的顺序性
(1)程序内部的顺序性
一个进程内部语句的执行顺序由程序本身规定,与调度顺序无关。
(2)程序外部的顺序性
指多个进程顺序执行,这些进程的执行在时间上没有重叠。本质上属于单任务调度,任何时刻仅存在一个进程。
二、程序执行的并发性
1、进程的并发性含义
进程的并发性是指一组进程的执行在时间上是重叠的,即一个进程执行的第一条指令是在另一个进程执行的最后一条指令完成之前开始的。
进程的并发性属于多任务调度,任何时刻可以存在多个进程交替穿插运行,即并发执行。
进程并发执行是调度的结果,不影响进程内部的顺序性。多个并发进程之间指令的执行顺序是不确定的,但是一个进程内部指令的执行顺序总是确定的,由程序本身规定,与调度方式、调度顺序无关。调度顺序决定多个任务使用处理器的顺序,任务内部指令的执行顺序是编制程序时规定好的,是固有的,与外部因素无关。
进程的并发性
程序内部的并发性——并发多线程 程序外部的并发性——并发多进程
2、并发程序设计
(由程序员)把一个程序编制为若干个可同时执行的程序模块的方法称为并发程序设计
并发多线程程序设计——如果并发执行模块都属于一个进程,在进程内部执行,则称为并发多线程程序设计;
并发多进程程序设计——若并发执行模块属于不同进程,则称为并发多进程程序设计。
并发程序设计的好处
能够同时启动多台设备操作,充分利用处理器与外围设备、外围设备与外围设备之间的并行工作能力,减少设备间的等待,提高资源利用率和计算机的工作效率。
而顺序程序设计则顺序操作设备,设备利用率较低。
3、并发进程分类
无关的并发进程(无合作)一组并发进程分别在不同的变量集合上操作,一个进程的执行与其他并发进程的进展无关,即一个并发进程不会改变另一个并发进程的变量值。
交互的并发进程(有合作)一组并发进程共享某些变量,一个进程的执行可能影响其他并发进程的执行结果。
【Bernstein条件⎯并发进程的执行与时间是否无关的判定方法】
三、与时间有关的错误
1、结果不唯一
对数据重叠修改导致修改信息丢失,结果不唯一。 例如,多人抢购到一张车票,一票售给多人。
2、永远等待
当合作进程之间等待、唤醒之类的同步信号发送次序颠倒时,等待进程因错过了唤醒信号而永远等待。 例如,归还资源的进程唤醒尚未等待资源的进程,唤醒信号丢失。
四、进程的交互:协作和竞争
1、并发进程之间的竞争关系
并发进程之间的竞争关系是由于并发进程共用一套计算机系统资源引起的,一个进程的执行可能影响与其竞争资源的其它进程。
资源竞争产生两个问题
-
死锁问题——进程直接或间接互相等待对方的资源;
-
饥饿问题——一些进程总是优先于另一些进程,解决:FCFS资源分配策略。
进程互斥——进程互斥是指若干进程要使用同一共享资源时,任何时刻最多允许一个进程使用,其他要使用该资源的进程必须等待,直到占有资源的进程释放该资源。解决办法——进程竞争关系(间接制约关系)的手段。管理工具**——临界区管理可以解决进程互斥问题。
2、并发进程之间的协作关系
-
协作产生原因——某些并发进程为完成同一任务而共享某些数据,形成协作关系。
-
协作方法——协作进程之间需要同步,即一个进程在接收到伙伴进程发来的信号之前需要等待
进程同步——指两个以上进程基于某个条件协调彼此的活动,一个进程的执行依赖于协作进程的消息或信号,当一个进程没有得到来自于协作进程的消息或信号时需等待,直到消息或信号到达才被唤醒。
解决——进程间协作关系(直接制约关系)的手段
进程互斥与同步的区别
相交进程之间的关系主要有两种,同步与互斥。
所谓互斥,是指散布在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。
所谓同步,是指散步在不同进程之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。
也就是说互斥是两个线程之间不可以同时运行,它们会相互排斥,必须等待一个线程运行完毕,另一个才能运行。
而同步也是不能同时运行,但他是必须要安照某种次序来运行相应的线程(也是一种互斥)!
总结
互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
同步:是指在互斥的基础上(大多数情况)通过其它机制实现访问者对资源的有序访问。
3.2 临界区管理
一、临界区调度原则
1、临界区与临界资源
并发进程中与共享变量有关的程序段叫做临界区,共享变量代表的资源叫做临界资源。
例如,车票销售进程中代表剩余可售票数的变量即为临界资源;读写该变量的程序段即为临界区。
并发进程中访问共享变量部分的程序段必须顺序执行,才能保证数据一致性。
2、临界区的调度原则
(1)一次至多允许一个进程进入临界区内执行;
(2)如果已有进程在临界区,其他试图进入的进程应等待;
(3)如果临界区空闲,则应允许进程进入临界区。
(4)进入临界区内的进程应在有限时间内退出,以便让等待进程中的一个进入。
二、实现临界区管理的硬件设施
1、关中断 进程在进入临界区之前先关中断,退出临界区时开中断。
在关中断期间,进度调度程序失去中断激活的机会,不会切换进程,保证了临界区的互斥执行。
关中断方法的缺点
(1)关中断时间过长会影响系统效率,限制处理器交叉执行程序的能力;
(2)关中断方法不适用于多CPU系统,因为,在一个处理器上关中断,并不能防止进程在其他处理器上执行相同的临界区代码;
(3)关中断权利赋予用户很危险,如果用户未开中断,系统可能因此终止。
2、测试并建立指令
硬件提供的测试并建立指令的过程如下:
TS(x) { 若x=true,则{x=false;return true;} 否则 return false; }
利用TS指令实现进程互斥的算法如下:
bool s=true; cobegin process Pi( ) { //i=1,2,...,n while(!TS(s)); //上锁 {临界区}; s=true; //开锁 } coend
3、对换指令
对换(Swap)指令的功能是交换两个字的内容,在Intel 80x86中,对换指令为XCHG指令。
用对换指令实现进程互斥的程序如下:
bool lock=false; cobegin Process Pi( ) {//i=1,2,...,n bool keyi=true; do { SWAP(keyi,lock); }while(keyi); //上锁 {临界区}; SWAP(keyi,lock);//开锁 } coend
3.3 信号量与PV操作
一、同步与同步机制
典型的进程同步问题:生产者-消费者问题
-
生产者进程——向其它进程输出或者发送数据的进程
-
消费者进程——从其它进程接收数据的进程
生产者-消费者问题描述
数据结构——有一环形缓冲池,包含n个缓冲区(0~n-1)。
操作:有两类进程:m个生产者进程和n个消费者进程,生产者进程向空的缓冲区中投放产品,消费者进程从满的缓冲区中取走产品。
要求 :采用算法描述生产者进程、消费者进程通过缓冲池交互的行为。
未考虑进程同步的生产者进程和消费者进程交互算法:
int k; //缓冲池中缓冲区个数 typedef anyitem item; //产品类型 item buffer[k]; //缓冲池 int in=0,out=0,counter=0; //读写指针和满缓冲区个数 process producer(void) //生产者进程 { while (true) { //无限循环 {produce an item in nextp}; //生产一个产品 if (counter==k) sleep(producer);//缓冲满时,生产者睡眠 buffer[in]=nextp; //将一个产品放入缓冲区 in=(in+1)%k; //指针推进 counter++; //缓冲内产品数加1 if(counter==1) wakeup(consumer);//缓冲池非空后唤醒消费者 } } process consumer(void) //消费者进程 { while (true) {//无限循环 if (counter==0) sleep(consumer);//缓冲区空,消费者睡眠 nextc=buffer[out]; //取一个产品到nextc out=(out+1)%k; //指针推进 counter--; //取走一个产品,计数减1 if(counter==k-1) wakeup(producer);//缓冲不满,唤醒生产者 {consume the item in nextc}; //消耗产品 } }
进程对缓冲池的竞争关系
生产者与生产者、生产者与消费者、消费者与消费者
进程并发执行时可能出现的错误
-
多个生产者将多个产品放入同一个缓冲区中(结果不唯一)
-
生产者无法正常唤醒消费者,导致缓冲区满,所有进程睡眠(永远等待)
-
多个消费者从同一个满缓冲区中取产品(结果不唯一)
进程并发错误的解决方法—— 利用进程同步机制控制进程的相对速率
同步机制
-
信号量与PV操作
-
消息传递
-
管程
二、信号量与PV操作
1、临界区调度尝试算法中存在的问题
(1)对不能进入临界区的进程,采用忙式等待测试法,浪费CPU时间。
(2)将测试能否进入临界区的责任推给各个竞争的进程会削弱系统的可靠性,加重用户编程负担。
2、信号量同步机制的提出
1965年荷兰计算机科学家E.W.Dijkstra提出新的同步工具⎯信号量和P、V操作。
他将交通管制中使用多种颜色信号灯管理交通的方法引入操作系统
操作系统中信号量的物理意义
在操作系统中,信号量是用来表示物理资源的实体,信号量是一种软资源,是一个与队列有关的整型变量。
信号量的实现结构
信号量实现为记录型数据结构,包含两个分量:一个是信号量的值,另一个是信号量队列的队列指针
Dijkstra发明了两个信号量操作原语:P操作原语、V操作原语
信号量和P、V操作的功能:
-
解决并发进程的竞争互斥问题
-
解决并发进程的协作同步问题
3、信号量的分类(按用途)
-
公用信号量:初值常常为可用资源数,多用来实现进程同步。拥有该信号量的一类进程可以对其执行P操作,而另一类进程可以对其执行V操作。
-
私有信号量:初值常常为1,用来实现进程间的互斥。相关进程均可对其执行P、V操作。
4、一般信号量的结构和操作描述
设s为一个记录型数据结构: 一个分量为整型量value;另一个为信号量队列queue
P和V操作原语定义:
P(s):将信号量s减去1,若结果小于0,则调用P(s)的进程被置成等待信号量s的状态。
V(s):将信号量s加1,若结果不大于0,则释放一个等待信号量s的进程。
信号量的数据结构
typedef struct semaphore { int value; //信号量值 struct pcb *list; //信号量队列指针 } semaphore; P操作 void P(semaphore &s) { s.value--; if(s.value<0) W(s.list); //将P操作调用者进程置为阻塞状态并移入s信号量队列,转进程调度 } V操作 void V(semaphore &s) { s.value++; if(s.value<=0) R(s.list); //从信号量s队列中释放一个等待信号量s的进程并转换成就绪态,自己则继续执行 }
变量说明:P(s)和V(s)中的s为两个过程的共享 变量说明变量。s的初值根据其用途设置。
P、V操作含义:
P操作意味着请求一个资源;V操作意味着释放一个资源
W(s.list)和R(s.list)是操作系统的基本系统调用。
推论
1:若s>0,则s值代表可用物理资源数
2:若s<0,则|s|代表等待s资源的进程数
3:P操作意味着请求一个资源,V操作意味着释放一个资源。在一定条件下,P操作代表挂起进程操作,而V操作代表唤醒被挂起进程的操作
三、信号量的应用⎯利用信号量实现互斥
1、方法 为临界资源设一互斥信号量mutex,初值为1;
将临界区置于P(mutex)和V(mutex)之间;
P(mutex)和V(mutex)一定成对出现在同一个进程中。
2、应用模式
semaphore mutex; mutex=1; cobegin process Pi( ) { //i=1,…,n P(mutex); {临界区}; V(mutex); } coend
四、信号量的应用⎯利用信号量实现进程同步
几个经典进程同步问题:
(1)哲学家进餐问题
(2)生产者-消费者问题
(3)读者-写者问题
(4)睡眠理发师问题
1、哲学家进餐问题
为了吃面,每个哲学家必须获得两把叉子,且每人只能从自己左边或右边去取叉子。
伪代码:
semaphore fork[5]; for (int i=0;i<5;i++) fork[i]=1; cobegin process philosopher_i( ) { //i= 0,1,2,3,4 while(true) { think(); P(fork[i]); P(fork[(i+1)%5]); eat( ); V(fork[i]); V(fork[(i+1)%5]); } } coend
哲学家进餐死锁问题解决方案:
(1)至多允许四位哲学家同时去拿左边的叉子
(2)规定奇数号哲学家先拿他左边的叉子,然后再去拿右边的叉子;偶数号哲学家先拿他右边的叉子,然后再去拿左边的叉子;
(3)仅当哲学家的左右两把叉子均可用时,才允许他拿起叉子进餐,否则一把叉子也不取。
存在互斥关系的进程 ——相邻两个哲学家两两互斥
理由:所有哲学家属于同类事物,地位对等,对同一信号量的P、V操作位于同一进程中,且信号量初值为1
2、生产者-消费者问题 指存在数据供给与需求关系的 生产者-消费者两类进程。
实现生产者-消费者问题的数据结构设计:
(1)临界资源:含有n个缓冲区的公用缓冲池
(2)互斥信号量mutex:实现诸进程对缓冲池的互斥使用,一次仅允许一个进程读或写公用缓冲池,初值为1
(3)资源信号量empty: 记录空缓冲区个数,初值为n
(4)资源信号量full:记录满缓冲区个数,初值为0
生产者-消费者伪代码
item B[k]; semaphore empty; empty=k; //可以使用的空缓冲区数 semaphore full; full=0; //缓冲区内可以使用的产品数 semaphore mutex; mutex=1; //互斥信号量 int in=0; //写缓冲区指针 int out=0; //读缓冲区指针 cobegin process producer_i( ) //生产者进程 { while(true) { produce( ); P(empty); P(mutex); append to B[in]; in=(in+1)%k; V(mutex); V(full); } } process consumer_j( ) //消费者进程 { while(true) { P(full); P(mutex); take( ) from B[out]; out=(out+1)%k; V(mutex); V(empty); consume( ); } } coend
生产者-消费者问题同步与互斥关系总结(1)
存在同步关系的进程 ——生产者与消费者
存在互斥关系的进程:
-
生产者与生产者
-
生产者与消费者
-
消费者与消费者
同时存在同步与互斥关系的进程 ——生产者与消费者
同步操作的特征:
-
唤醒异类,而不是同类
-
消费者进程中的V(empty)只能唤醒生产者,不会唤醒消费者
-
生产者进程中的V(full)只能唤醒消费者,不会唤醒生产者
互斥操作的特征:唤醒同类,也唤醒异类
-
消费者进程中的V(mutex)既会唤醒消费者,也会唤醒生产者
-
生产者进程中的V(mutex)既会唤醒生产者,也会唤醒消费者
3、读者-写者问题 问题描述:若干读者(Reader)进程和写者(Writer)进程共享一个数据文件,允许多个Reader进程同时读一个共享对象,但不允许一个Writer进程与其它Reader进程或Writer进程同时访问共享对象。
读者-写者问题运行场景分析:
假设读者r1、r2、写者w1依次到来,r1、r2读完退出共享数据文件后w1可以写,写完之前读者r3、写者w2先后到来。
读者-写者问题互斥关系的特殊性(1)
由多个读者构成的读者进程集合与单一的某个写者进程之间存在互斥关系。读者-写者问题的互斥关系特殊性在于:即互斥关系不是一对一的,而是多对一的。
读者-写者问题互斥关系的特殊性(2)
虽然读者进程算法描述中的P(writeblock)和V(writeblock)成对出现,但并非每个读者进程都执行P(writeblock)或V(writeblock)
只有第1个读者进程会执行P(writeblock)
只有最后1个读者进程会执行V(writeblock)
非第1也非最后1个读者进程对P(writeblock)和V(writeblock)都不会执行
当第1个读者进程也是最后1个离开的读者进程时,它会执行P(writeblock)和V(writeblock)
事实上,某个读者进程执行P(writeblock)V(writeblock)的行为代表的是整个读者进程集合的行为,而不仅仅是执行该操作的那个读者进程的个体行为。
第1个读者进程和最后1个读者进程负责执行所有读者进程与某个写者进程之间的互斥操作,建立它们与单个写者进程之间的互斥关系。
因此,在判定进程之间的互斥关系时,要从静态结构即算法描述和动态行为即进程执行两方面来考察。
静态方面看算法描述中同一信号量的P、V操作是否成对出现在同一个进程中;
动态方面看每个进程执行时是否成对执行该进程算法描述中同一信号量的P、V操作。
读者-写者问题同步与互斥关系总结:
存在互斥关系的进程:
-
单个读者与单个读者
-
单个写者与单个写者
-
所有读者与单个写者
4、睡眠理发师问题
理发店有一位理发师、一把理发椅和n把椅子供顾客等候理发休息。如果没有顾客,理发师便在理发椅上睡觉。 一个顾客到来时,他必须叫醒理发师。
如果理发师正在理发时又有顾客到来,则如果有空椅子可坐,顾客就坐下来等待,否则离开。
cobegin process barber( ) //理发师进程 { while(true) { P(customers);//有顾客可供消费吗?若无顾客,理发师睡眠 P(mutex); //若有顾客时,以顾客当产品,取一个顾客消费 waiting--; //等候顾客数少一个 V(barbers); //理发师喊一个顾客来准备为他理发 V(mutex); //退出临界区 cut_hair(); //理发师正在理发(非临界区) } } process customer_i( ) //顾客进程 { P(mutex); //进入临界区 if(waiting<CHAIRS) {//若有空椅子,则等候顾客数加1,否则顾客离开 waiting++; V(customers); //可用顾客数增1 V(mutex); //退出临界区 P(barbers); //理发师忙,顾客坐下等待 get_haircut(); //否则顾客坐下理发 } else V(mutex); //人满了,走吧! } coend
睡眠理发师问题同步与互斥关系总结
存在同步关系的进程 理发师与顾客
存在互斥关系的进程 理发师与顾客、顾客与顾客
五、Linux系统中的同步互斥功能
1、信号量初始化函数sem_init
头文件:#include<semaphore.h>
原型:int sem_init(sem_t *sem, intpshared, unsigned int value);
说明:sem_init()初始化sem信号量。value参数指定信号量的初始值。pshared 参数指明信号量由进程内线程共享,还是由进程之间共享。
2、信号量P操作函数sem_wait
头文件:#include<semaphore.h>
原型:int sem_wait(sem_t * sem);
说明:sem_wait函数减小sem信号量的值。如果信号量的值大于0,则进行减一的操作,函数立即返回。如果信号量当前值为0,那么调用就会一直阻塞,直到信号量变得可以进行减一的操作(例如,信号量的值大于0)或者信号处理程序中断调用。
3、信号量V操作函数sem_post
头文件:#include<semaphore.h>
原型:int sem_post(sem_t *sem);
说明:sem_post函数使sem信号量的值增1,并唤醒阻塞在这个信号量上的一个进程或线程。
六、Linux进程同步与互斥实验:信号量解决生产者-消费者问题
采用多线程技术实现生产者-消费者之间的同步互斥操作。
共享环形缓冲区的存储单元个数为10,即可以放置10个产品,各个生产者线程放入的产品是该生产者进程的编号。
任意一个消费者线程可取缓冲区当前可取的产品。
3.4 管程
一、管程的概念
1、为什么要引入管程
(1)把分散在各进程中的临界区集中起来进行管理;
(2)防止进程有意、无意的违法同步操作;
(3)便于用高级语言书写程序和程序正确性验证。
2、管程的定义
管程是由局部于自己的若干公共变量及其说明和所有访问这些公共变量的过程所组成用来实现同步互斥功能的软件模块。
管程组成部分 :
-
局部于管程的共享变量
-
对数据结构进行操作的一组过程
-
对局部于管程的数据进行初始化的语句
3、管程的属性
(1)共享性
管程可被系统范围内的进程互斥访问,属于共享资源
(2)安全性
管程的局部变量只能由管程的过程访问,不允许进程或其它管程直接访问,管程也不能访问非局部于它的变量。
(3)互斥性
多个进程对管程的访问是互斥的。任一时刻,管程中只能有一个活跃进程
(4)封装性
管程内的数据结构是私有的,只能在管程内使用,管程内的过程也只能使用管程内的数据结构。进程通过调用管程的过程使用临界资源
4、管程语法形式
type 管程名=monitor{ 局部变量说明; 条件变量说明; 初始化语句; define 管程内定义的、管程外可调用的过程或函数名列表; use 管程外定义的,管程内将调用的过程或函数名列表;
5、管程结构
-
局部数据和条件变量组成管程内的数据结构
-
过程/函数1~过程/函数k组成管程内的一组过程,对管程内的数据结构进行操作
-
初始化代码对管程内的数据结构进行初始化
管程各部件说明
(1)管程入口处的等待队列
管程是互斥进入的,当一个进程试图进入一个已被占用的管程时,它需在管程入口处队列中等待。
(2)管程内的资源等待队列
管程是用于管理资源的,进入管程的进程等待资源时加入资源等待队列,该队列由条件变量维护。
资源等待队列可以有多个,每种资源一个队列。
(3)条件变量
条件变量是管程内的一种数据结构,只有在管程中才能被访问,它对管程内的所有过程是全局的,只能通过两个原语操作来控制它。
c.wait( )
c.signal( )
调用进程阻塞并移入与条件变量c相关的资源队列中,并释放管程,直到另一个进程在条件变量c上执行signal( )唤醒等待进程并将其移出条件变量c队列。
如果存在其他进程由于对条件变量c执行wait( )而被阻塞,则释放之;如果没有进程在等待,那么,信号被丢弃。
条件变量与P、V操作中信号量的区别
条件变量是一种非计数信号量,维护队列时不对其中的等待进程计数。
因此在使用条件变量x时,通常需要定义一个与之配套使用的整型变量x-count用于记录条件变量x所维护等待队列中的进程数。
P、V操作中的计数信号量不仅维护相关队列,而且记录队列中进程数。
(4)管程内的紧急等待队列
当管程内的进程P唤醒等待队列中的另一个进程Q时,管程中便存在两个可运行进程。其中就绪进程需要加入就绪队列,设置在管程中的就绪队列称为紧急等待队列。
紧急等待队列的优先级高于入口等待队列的优先级。
二、管程的实现
霍尔方法使用P和V操作原语实现对管程中过程的互斥调用
1、Hoare管程数据结构
(1)mutex
信号量mutex管理管程入口处的等待队列,供管程中过程互斥调用,初值为1。
进程调用管程中的任何过程时,应执行P(mutex);进程退出管程时应执行V(mutex)开放管程,以便其它调用者进入。
进程在等待资源期间,应允许其它进程进入管程,故在wait操作中也必须执行V(mutex),否则会妨碍其它进程进入管程,导致无法释放资源。
(2)next和next-count
信号量next管理管程内的紧急等待队列,初值为0。凡发出signal操作的进程应该用P(next)挂起自己,加入紧急等待队列,直到被释放进程退出管程或产生其它等待条件。
进程在退出管程的过程前,须检查是否有别的进程在信号量next(即紧急等待队列)上等待,若有,则用V(next)唤醒它。
next-count初值为0,用来记录在next(即紧急等待队列)上等待的进程数目。
(3)x-sem和x-count
信号量x-sem用来管理资源等待队列,初值为0。进程申请资源得不到满足时,执行P(x-sem)挂起,加入x-sem所代表的资源队列。释放资源时,需要知道是否有别 的进程在等待资源,因此用计数器xcount(初值为0)录等待资源(即资源等待队列中)的进程数。
执行signal操作时,应使等待资源(即资源等待队列中)的某个进程立即恢复运行,而不使其它进程抢先进入管程,这可以用V(x-sem)来实现。
2、Hoare的wait操作
void wait(semaphore&x_sem, int&x_count, InterfaceModule&IM) { x_count++; if IM.next_count > 0 V(IM.next); else V(IM.mutex); P(x_sem); x_count--; }
3、Hoare的signal操作
void signal(semaphore&x_sem, int&x_count, InterfaceModule&IM) { if x_count > 0 { IM.next_count++; V(x_sem); P(IM.next); IM.next_count--; } }
三、管程的应用
管程解决生产者-消费者问题
type producer_consumer=monitor //管程定义 { item B[k]; //缓冲区个数 int in=0,out=0; //存取指针 int count=0; //缓冲中产品数 semaphore notfull=0,notempty=0; //条件变量 int notfull_count=0,notempty_count=0; InterfaceModule IM; define append,take; use enter,leave,wait,signal; void append(item x)管程的应用(2) { enter(IM); if(count==k) wait(notfull,notfull_count,IM); //缓冲已满,在notfull队列等待空白缓冲区 B[in]=x; in=(in+1)%k; count++; //增加一个产品 signal(notempty,notempty_count,IM); //唤醒notempty队列中的等待消费者,自己入紧 急等待队列 leave(IM); } void take(item &x)管程的应用(3) { enter(IM); if(count==0) wait(notempty,notempty_count,IM); //在notempty队列中等待满缓冲区 x=B[out]; out=(out+1)%k; count--; //减少一个产品 signal(notfull,notfull_count,IM); //唤醒notfull队列中的等待生产者 leave(IM); } } cobegin process producer_i() //进程定义 { item x; produce(x); producer_consumer.append(x); } process consumer_j() { item x; producer_consumer.take(x); consume (x); } coend
3.5 进程通信
一、管道通信机制
1、管道的概念
管道是连接读写进程的一个共享文件,允许进程以先进先出(FCFS)方式写入和读出数据,并对读写操作进行同步。发送进程以字符流形式把大量数据送入管道尾部,接收进程从管道头部接收数据。
管道的实现
管道可借助文件系统实现,包括(管道)文件的创建、打开、关闭和读写。
2、管道读写进程之间的同步
(1)管道应互斥使用,管道读写不能同时进行。一个进程正在执行管道写入或读出操作时,另一进程须等待。读写结束时,唤醒等待进程,自己则应阻塞。
(2)读写双方必须能够知道对方是否存在,只有存在才能通信。如果对方已经不存在,就没有必要再发送或接收信息。
(3)管道空间大小通常是固定的,读写操作时需要考虑写满和读空问题。
3、管道的类型
(1)匿名管道:仅存在于内存中的临时对象,仅用于具有共同祖先进程的父子进程或兄弟进程之间的通信。
(2)有名管道:又称为FIFO,具有与之关联的文件名、目录项和访问权限,无亲缘关系的进程可以通过引用有名管道的名字进行通信。
二、共享内存通信机制
1、共享内存的概念
共享内存是允许两个或多个进程共同访问的物理内存区域,是实现进程通信的一种手段。
2、共享内存区到进程虚拟地址空间的映射
共享内存区映射到进程中未使用的虚地址区,以免与进程映像发生冲突。共享内存区属于临界资源,读写共享内存区的代码属于临界区。
3、共享内存的主要操作
(1)创建共享内存
第一个进程创建共享内存,其它进程则通过创建操作获得共享内存标识符,并据此读写共享内存。
(2)共享内存绑定
通信进程将先前创建的共享内存映射到自己的虚拟地址空间,使共享内存成为进程地址空间的一部分。
(3)共享内存解除绑定(断开共享内存链接)
通信结束,解除共享内存到通信进程虚地址空间的映射。
(4)撤销共享内存
当所有进程不再需要共享内存时删除共享内存。
三、消息传递通信机制
1、消息的概念
消息是格式化的数据,在计算机网络中称报文。消息由消息头和消息体组成。
消息:消息头,消息体
2、消息传递通信机制的组成
消息传递通信机制:
由信箱、发送原语(send)和接收原语(receive)组成。
信箱:是存放信件的存储区域,每个信箱可分成信箱头和信箱体两部分。
信箱头:指出信箱容量、信件格式、信件位置指针等;
信箱体:用来存放信件,可分成若干个区,每个区容纳一个信件。
原语send(A,信件):若信箱未满,则把把一封信件(消息)发送到信箱A,同时唤醒信件等待者进程,否则发送者阻塞。
原语receive(A,信件):若信箱不空,则从信箱A接收一封信件(消息),同时唤醒等待发送者进程;否则接受者阻塞。
发送原语和接收原语封装了同步细节,其中包含阻塞唤醒机制。
3、利用消息传递通信机制解决同步与互斥
(1)利用消息传递通信机制解决互斥
首先创建一个共享信箱,并向其中发送一条空消息,希望进入临界区的进程首先试图接收一条消息,如果信箱为空,则进程阻塞;一旦获得消息,进程进入临界区,然后把该消息放回信箱。
(2)利用消息传递通信机制解决生产者-消费者问题
分别创建产品信箱productbox和空消息信emptybox,产品信箱productbox最初为空,空消息信箱emptybox最初填满空消息。
生产者从信箱emptybox中取出一条空消息,将产品加入其中形成满消息(产品消息),发送到产品信箱productbox。
消费者从信箱productbox中取出一条产品消息消费后,向emptybox信箱发送一条空消息。
利用消息传递通信机制解决生产者-消费者问题的算法
int capacity=缓冲大小, i ; void producer ( ) { message pmsg; while(true) { receive(emptybox, pmsg); pmsg=produce( ); send(productbox,pmsg); } } void consumer ( ) { message cmsg; while(true) { receive (productbox,cmsg); consume(csmg); send(emptybox,null); } } void main() { creat-mailbox(productbox); creat-mailbox(emptybox); for(i=0;i<capacity;i++) send(emptybox,null); parbegin (producer ,consumer); }
4、Linux消息队列通信机制
Linux消息队列通信机制属于消息传递通信机制。
消息队列是内核地址空间中的内部链表,每个消息队列具有唯一的标识符。
消息可以顺序地发送到队列中,并以几种不同的方式从队列中获取。
Linux消息队列的主要操作函数
(1)msgget
创建一个消息队列或者返回已存在消息队列的标识号;
(2)msgsnd
向一个消息队列发送一个消息;
(3)msgrcv
从一个消息队列中接收一个消息;
(4)msgctl
在消息队列上执行指定的操作,如执行检索、删除等操作。
四、套接字(Socket)通信机制
1、套接字的概念
套接字(Socket)通信允许互联的位于不同计算机上的进程之间实现通信功能。
套接字用于标识和定位特定计算机上特定进程的地址,以便数据准确传输给目标进程。
2、套接字的组成
套接字(Socket)包含三个参数:
-
通信的目的IP地址
-
使用的传输层协议(TCP或UDP)
-
使用的端口号
IP地址 ——用于标识目标计算机
端口号——用于标识目标计算机上的特定进程
4、套接字通信过程
套接字通信进程分为 服务器端进程、客户端进程
套接字之间的连接过程分为三个步骤
服务器监听
服务端套接字并不定位具体的客户端套接字,而是处于等待连接的状态
客户端请求
客户端套接字提出连接请求,连接服务器端套接字
连接确认
服务器端套接字监听到客户端套接字的连接请求时,响应请求,建立一个新的线程,把服务器端套接字的信息发送给客户端,客户端确认后连接即可建立。
五、信号通信机制
1、信号的概念
信号是一种软中断信号,是对硬件中断机制的软件模拟,利用信号可以实现进程间的通信,一个进程可以向另一进程发送某一信号通知该进程某个异常事件发生。
接收信号的进程被中断,对该信号代表的事件进行处理
2、信号的产生源
(1)用户
用户输入<Ctrl>+c,或终端驱动程序分配给信号控制字符的其它任何键来请求内核产生信号
(2)内核
当进程执行出错时,内核检测到事件并给进程发送信号
例如,非法段存取、浮点数溢出、或非法操作码,内核利用信号通知进程种种特定事件发生
(3)进程
进程可通过系统调用kill给另一个进程发送信号
3、信号的检测和响应过程
在中断或异常处理程序末尾,进程从核心态返回用户态之前,或时钟中断结束之前,系统调用内核函数do_signal()检查该进程是否收到信号,若是则执行handle_signal()使进程返回用户态转入信号处理程序执行。
信号处理结束后,执行系统调用sigreturn()陷入内核,内核做好善后工作后返回用户态,回到应用程序断点执行。
3.6 死锁
一、死锁的概念、产生原因和必要条件
1、死锁的概念
如果在一个进程集合中的每个进程都在等待只能由该集合中的其它进程才能引发的事件,而无限期陷入僵持的局面称为死锁。
死锁产生因素:
-
系统拥有的资源数量
-
资源分配策略
-
进程对资源的使用要求
-
并发进程的推进顺序
2、死锁产生的必要条件
(1)互斥条件——进程互斥使用资源,一旦某个资源被占用,欲使用该资源的进程必须等待
(2)占有和等待条件(部分分配条件)——进程申请新资源得不到满足而等待时,不释放已占有资源
(3)不剥夺条件——一个进程不能抢夺其它进程占有的资源
(4)循环等待条件(环路条件)——存在一组进程循环等待资源的现象
前三个条件是死锁产生的必要条件,不是充分条件。
第四个条件是前三个条件同时存在时产生的结果,只要破坏这四个条件之一,死锁就可防止。
二、死锁防止
死锁防止通过破坏产生死锁的四个条件之一来实现
死锁防止方法:
1、破坏互斥条件——使资源可同时访问而不是互斥使用。该办法对于磁盘适用,对于磁带机、打印机等多数资源不仅不能破坏互斥使用条件,还要加以保证。
3、破坏不剥夺条件——静态分配可以破坏占有和等待条件。 静态分配是指一个进程必须在执行前就申请它所需要的全部资源,并且直到它所需要的资源都得到满足后才开始执行。资源利用率低。
2、破坏占有和等待条件——即采用剥夺式调度方法。 当进程申请资源未获准许时,在等待前主动释放资源。剥夺调度方法目前只适用于内存资源和处理器资源。
4、破坏循环等待条件——采用层次分配策略可以破坏循环等待条件。 层次分配策略将资源被分成多个层次,进程按照由低到高的层次顺序申请和得到资源,按照由高到低的层次顺序释放资源。 当进程得到某一层的一个资源后,如果需要申请该层的另一个资源,则必须先释放该层中的已占资源。
三、死锁避免
1、避免死锁的策略
死锁避免方法允许系统中同时存在死锁的三个必要条件,即互斥、占有且等待和非抢占;每当进程提出资源申请时,系统分析满足该资源请求时系统是否会发生死锁,若不会发生则实施分配,否则拒绝分配。
银行家算法就是避免死锁的一种方法。
2、银行家算法思想
一个银行家拥有资金M,被N个客户共享,银行家对客户提出下列约束条件:
1)每个客户必须预先说明自己所要求的最大资金量;
2)每个客户每次提出部分资金量申请和获得分配;
3)如果银行满足了客户对资金的最大需求量,则客户在资金运作后一定可以很快归还资金。
银行家算法与操作系统死锁问题的对应关系
银行家——操作系统
周转资金——计算机资源
客户——进程
3、银行家算法在死锁问题上的应用步骤:
(1)系统中的所有进程进入进程集合
(2)在安全状态下对进程请求的资源进行试探性分配
(3)系统用剩余的可用资源和进程集合中其它进程还要的资源数作比较,找到剩余资源能满足最大需求量的进程A,保证A运行完毕并归还全部资源
(4)把进程A从集合中去掉,相当于回收其资源。如果进程集合非空,则返回(2)
(5)若进程集合为空,则系统处于安全状态,可实施本次分配;否则,系统处于不安全状态,本次资源分配暂不实施,申请进程等待
4、银行家算法的缺点
使用银行家算法时,很难在进程运行前知道其所需的资源最大量
而且算法要求系统中的进程必须是无关的,相互间没有同步要求
进程的个数和分配的资源数目应该是固定的。
这些要求事先难以满足,因而银行家算法缺乏实用价值
四、死锁检测与解除
1、死锁检测策略
死锁检测和解除对资源分配不加任何限制,也不采取死锁避免措施,但系统定时运行一个“死锁检测”程序,如果检测到系统发生了死锁,再采取措施解除它。
死锁检测依据的数据结构
进程-资源分配图进程-资源分配图是描述进程和资源间申请与分配关系的一种有向图,可用以检测系统是否处于死锁状态。
2、进程-资源分配图的结构
进程-资源分配图——由进程结点P、资源结点R和有向边组成。
有向边:
-
请求边:从进程指向资源的有向边Pi→Rj为请求边,表示进程Pi申请资源类Rj中的一个资源。
-
分配边:从资源指向进程的有向边Rj→Pi为分配边,表示Rj类中的一个资源已分配给进程Pi。
3、进程-资源分配图与死锁判断的关系
(1)如果进程-资源分配图中无环路
则此时系统没有发生死锁
(2)如果进程-资源分配图中有环路,且每个资源类中仅有一个资源
则系统中发生了死锁,此时,环路是系统发生 死锁的充要条件,环路中的进程便为死锁进程
(3)如果进程-资源分配图中有环路,且涉及 的资源类中有多个资源
则环的存在只是产生死锁的必要条件而不是充分条件
4、死锁的检测和解除方法
从进程-资源分配图中找到一个既不阻塞又非独立的进程,消去所有与该进程相连的有向边,相当于该进程能够执行完成而释放资源,回收资源使之成为孤立结点。
然后将所回收的资源分配给其它进程,再从进程-资源分配图中找到下一个既不阻塞又非独立的进程,消去所有与该进程相连的有向边,使之成为孤立结点……。
不断重复该过程,直到所有进程成为孤立结点,则称该图是可完全化简的;否则称该图是不可完全化简的。
死锁定理
系统为死锁状态的充分条件是:当且仅当该状态的进程-资源分配图是不可完全简化的。该充分条件称为死锁定理。
5、死锁检测算法与死锁避免算法比较
死锁检测算法考虑了检查每个进程还需要的所有资源能否满足要求;
死锁避免算法则仅根据进程的当前申请资源量来判断系统是否进入了不安全状态。
在银行家算法中,一次仅允许一个进程提出资源请求,做安全分析并分配资源后,才允许下一个进程提出资源请求。
死锁检测算法处理的进程-资源图中可以同时存在多个进程的请求边。
6、死锁的解除方法
(1)立即结束所有进程的执行,并重新启动操作系统。以前工作全部作废,损失可能很大。
(2)剥夺陷于死锁的进程占用的资源,但并不撤销它,直至死锁解除。
(3)撤销陷于死锁的所有进程,解除死锁继续运行。
(4)逐个撤销陷于死锁的进程,回收其资源,直至死锁解除。
(5)根据系统保存的检查点,使所有进程回退,直到足以解除死锁。
(6)当检测到死锁时,如果存在某些未卷入死锁的进程,且它们会进一步建立一些新的抑制进程能执行到结束,则它们可能释放足够的资源来解除死锁。
第四章 存储管理
4.1 存储器层次
1、寄存器
存储管理的功能:
-
内存分配和回收
-
内存抽象和映射
-
存储隔离和共享
-
存储扩充
位于CPU中,访问速度最快
2、高速缓存
位于CPU中,用于存放从内存预取的指令或数据
3、主存储器
操作系统存储管理的主要对象,是进程活动的重要场所。
主存容量大,可以同时容纳多个进程。
OS需要对内存分块管理。
I/O操作也依托于主存。
4、磁盘和磁带
永久保存信息,掉电后信息依然存在
磁盘和磁带存储的信息可长期保存。磁盘和磁带被看做I/O设备,属于设备管理的范畴。
又由于磁盘和磁带是软件信息的主要存储场所,因此文件管理也会涉及磁盘及磁带空间的管理。
4.2 地址重定位、存储保护和存储共享
1、逻辑地址与物理地址
地址重定位或地址变换
在执行程序时,将其中的逻辑地址转变为物理地址的过程。
逻辑地址
逻辑地址是与程序在内存中的物理位置无关的访问地址。
在执行对内存的访问之前必须把逻辑地址转换为物理地址。
包括:
-
源程序中的符号地址
-
编译生成的中间代码程序(也称为目标代码程序)地址
-
链接生成的可执行程序中的地址
物理地址(或绝对地址)
物理地址是程序运行时中央处理器实际访问的内存单元地址。 相对地址
相对地址是逻辑地址的一个特例,是相对于已知点(通常是程序的开始处)的存储单元的地址。
逻辑地址或相对地址也称为虚拟内存地址。
逻辑地址空间
一个用户作业的目标程序的逻辑地址集合称为该作业的逻辑地址空间。
物理地址空间
主存中实际存储单元的物理地址的总体构成用户程序实际运行的物理地址空间。
2、静态重定位和动态重定位
静态重定位
根据程序所装入的内存位置由装入程序依据重定位信息一次性将程序中所有的逻辑地址转变为物理地址,然后程序开始执行,这种重定位方式称为静态重定位(可重定位装入方式)。
特点
静态重定位无须硬件支持,易于实现。
静态重定位不允许程序在内存中移动位置。
动态重定位
地址转换工作穿插在指令执行的过程中,每执行一条指令,CPU对指令中涉及的逻辑地址进行转换,这种重定位方式称为动态重定位(动态运行时装入方式)。
特点
动态重定位必须借助硬件地址转换机构实现。 动态重定位允许程序在内存中移动位置。
动态重定位的具体操作
程序装入内存后,其中的逻辑地址保持不变,程序在内存的起始地址装入到硬件专用寄存器⎯重定位寄存器中。
地址变换公式——物理地址=逻辑地址+内存始址
重定位寄存器数目、程序地址结构、程序物理、内存空间连续性
重定位寄存器可以有多个,分别用于程序段、数据段以及堆栈段等的重定位。
这意味着程序地址结构是二维的,包括段地址和段内偏移。
程序所在物理内存空间可以是离散的,不必连续。
在Intel x86 CPU中,CS、DS、ES、SS、FS、GS段寄存器即起到重定位寄存器的作用。
重定位寄存器与进程切换
重定位寄存器内容是进程上下文的一部分,进程切换时,重定位寄存器内容要一并切换。
重定位寄存器的信息通常保存在进程控制块中。进程上下文切换时,当前运行进程的重定位寄存器的内容及其它信息保护在进程控制块中,新进程重定位寄存器的内容及其它信息从其进程控制块中恢复,进程从断点开始继续执行。
3、存储保护
存储保护包括:
地址越界保护——对进程执行时所产生的所有主存访问地址进行检查,确保进程仅访问自己的主存区,这就是地址越界保护。
信息存取保护——进程访问分配给自己的主存区时,系统要对访问权限进行检查,如检查是否允许读、写、执行等,从而确保数据的安全性和完整性,防止有意无意的误操作而破坏主存信息,这就是信息存取保护。
程序的合法访问范围
各道程序只能访问自己的主存区而不能跳转到另一个进程中,尤其不能访问操作系统的任何部分。
4、存储共享
当多个进程执行一个程序,或者多个进程合作完成同一个任务需要访问相同的数据结构时,内存管理系统都要提供存储共享机制,以对内存共享区域进行受控访问。
4.3 连续存储管理
一、固定分区存储管理
连续存储管理
连续存储管理对每个进程分配一个连续的存储区域。
目前流行的存储管理技术
目前的操作系统多采用基于分页和分段的虚拟存储管理系统。
连续存储管理包括:固定分区存储管理、可变分区存储管理
1、固定分区存储管理方案
固定分区存储管理将内存空间划分为若干个位置和大小固定的连续区域,每一个连续区域称为一个分区,各分区大小可相同,也可不同。
分区划分的时机和划分的数目
由系统操作员和操作系统初始化模块在系统开机启动时,根据当天作业情况把主存划分成大小可以不等但位置固定的分区。
固定分区方案的缺点
(1)分区数目和大小在系统启动阶段已经确定,限制了系统中活动进程的数目,也限制了当前分区方案下可运行的最大进程。
(2)当分区长度大于其中进程长度时,造成存储空间浪费
内部碎片:由于进程所在分区大于进程大小而造成的分区内部浪费部分称为内部碎片。
二、可变分区存储管理
可变分区存储管理方法
按照作业的大小划分分区,划分的时间、大小和位置都是动态的,属于一种动态分区方法。
三、伙伴系统
伙伴系统
也称为buddy算法,是固定分区和可变分区折中的主存管理算法,由Knuth在1973年提出。
伙伴系统采用称为伙伴的可以分割、合并的不同规格的内存块作为分区单位。
1、伙伴的概念
两个大小相等且由同一个尺寸为2i(幂数)的空闲块分割而来的内存块互为伙伴。
2、伙伴系统内存分配与回收
分配
运用伙伴系统分配内存空间的过程是一个对空闲内存区不断对半切分,直到切分出的内存块为大于或等于进程大小的最小伙伴为止的过程。
回收
伙伴系统回收内存的过程是不断将相邻空闲伙伴合并为更大伙伴单位,直到伙伴不空闲,无法合并为止的过程。
4.4 分页存储管理
一、分页存储管理方案
1、页框和页
物理块或页框
分页存储管理将全部内存划分为长度相等的若干份,每一份称为一个物理块或页框。
页或页面
作业自动被分页系统划分为与每个物理块相等的若干等份,每一份称为一页或一个页面。
分页系统存储分配方法
一个作业的任一页可以装入到内存任一空闲物理块,并不要求逻辑上相邻的页所在内存物理块也相邻。
2、分页存储管理的地址结构
逻辑地址结构 页号 + 页内位移
物理地址结构 物理块号 + 块内位移
3、分页存储管理的地址变换
由于页内位移和块内位移相同,分页存储管理的地址变换演变为页号到物理块号的映射,即根据页号获得物理块号。
页表
页表用于实现地址变换,页表记载了逻辑地址到物理地址的对应关系,操作系统需为每个作业建立一张页表,系统通过页表可以准确访问内存中属于一个作业的所有页面。
4、分页地址变换的硬件支持
分页存储管理采用动态重定位技术,重定位寄存器的设置方法有两种:
一种是为每个页面设立一个重定位寄存器,整个页表放在重定位寄存器中,造价较高。
第二种方法是把页表存放在内存,系统另设一个页表始址寄存器和长度控制寄存器用来存放当前运行作业的页表始址和页表长。当前占有处理器的进程是页表寄存器的使用者,一旦进程出让了处理器,同时也应出让页表寄存器
二、快表(略)
三、分页存储空间分配和释放
分页系统存储管理数据结构
分页系统需要记录:每个物理块的忙闲情况+当前可用的空闲块总数
分页系统两种数据结构:位示图(位示图由一些二进制位组成,每一位对应一个内存物理块,位值表示所对应的物理块是否已分配出去。分配和回收物理块时只需修改位值即可。)+主存分配链表(表中结点信息包括:物理块忙闲标志、物理块起始地址、块数、指向下一结点的指针)
主存分配链表性能分析
结点数目是影响主存分配链表使用效率的重要因素。
当链表中的结点数目较多时,链表本身消耗较多内存空间,导致使用效率不高。
四、分页存储空间页面共享与保护
1、存储共享
分页系统实现存储共享时,必须区分
数据共享——允许不同的作业对共享的数据页使用不同的页号,只要令各自页表中的有关表目指向共享的数据信息块就行了。
程序共享——被共享的程序段中的逻辑地址在不同的进程空间必须是相同的。即对共享的程序必须规定一个统一的页号。
2、信息保护
分页系统实现信息保护的办法是
在页表中增加一些标志位,用来指出该页的信息操作权限
-
可读/写
-
只读
-
只可执行
-
不可访问
五、多级页表
1、多级页表的思想
页表离散存储,按需调入
如果页表很大,页表占用的内存物理块也允许是离散的,而且页表也可以按需装入内存,这样就需要再建立页表的页表,即页目录,这就是二级页表机制。
需要的还可建立更多级的页表。
推论——无论多少级页表 顶级页表 必须完全驻留内存
二级页表机制
系统为每个进程建一张页目录表,它的每个表项对应一个页表页,而页表页的每个表项给出页面和页框的对应关系。
页目录表是一级页表,页表页是二级页表。
2、两级页表的地址结构
两级页表的逻辑地址结构
页目录号(一级页表号)+页号(二级页表号)+页内位移
3、两级页表的地址转换
地址分解—— CPU送出的逻辑地址被分解为三个部分:页目录号、页表页号和页内位移。
查找一级页表—— 根据页目录号查找页目录表中相应表项,获得页表页所在物理块号;
查找二级页表—— 在该物理块中查找页表页号,获得该页所在内存物理块号,该物理块号与页内位移拼接形成要访问数据的内存物理地址。
4.5 分段存储管理
1、分段存储管理的引入
程序的结构特征
程序通常具有一定的逻辑结构,例如分成若干个段,每个段包含若干数据块或程序模块(函数、过程)。因此,程序具有二维地址结构:段和段内偏移。
内存的结构特征
内存对用户呈现一维线性结构
分页、分区存储管理与程序结构的不一致性
纯粹的分页和分区存储管理将程序视为与内存一致的线性结构,即使程序实际上为分段的二维逻辑结构,这样就导致内存中的程序不易按程序逻辑组成访问。
解决问题的办法——采用分段存储管理,依照程序的逻辑结构划分和分配内存空间
分段存储管理
分段存储管理以段为单位进行存储分配,作业每一段被分配一个连续的主存空间,各段存储位置不一定相邻,各段大小不一。
2、分段存储管理的逻辑地址结构
分段存储管理的逻辑地址是二维的,包括:段号+段内位移
分段地址结构对用户是可见的,用户知道逻辑地址如何划分为段号和段内位移。
每个段的最大长度受地址结构的限制,每一个程序中允许的最多段数也会受到限制。
3、分段存储管理的地址转换机构(1)
分段存储管理数据结构 段表操作系统需为每个作业建立一张段表,用以登记每个段的段号、该段所在内存始址和段长度。
分段存储管理硬件支持 段表控制寄存器系统需设置一个段表控制寄存器用来存放当前占用处理器的作业的段表起始地址和长度。
4、段的共享和保护
共享段在内存中只有一个副本,不同作业段表中的项指向共享段基址。
与页共享类似,共享数据段在不同作业进程的段表中可以有不同的段号,共享代码段在不同作业进程的段表中须有相同的段号。
4.6 虚拟存储管理
一、虚拟存储器原理
1、虚拟存储器的定义
在具有层次结构存储器的计算机系统中,采用自动实现部分装入和部分对换功能,为用户提供一个比物理主存容量大得多的,可寻址的一种“主存储器”称为虚拟存储器。
虚拟存储器的好处:
-
小内存运行大进程
-
小内存运行较多进程
虚拟存储器的代价
-
以时间换空间,以较小的内存空间运行大的进程或较多的进程将消耗较多的进程对换时间
-
节省了空间,浪费了时间
大型商业软件安装时都要求配置足够的内存容量
2、实现虚拟存储器的基础——程序执行的局部性原理
程序执行的局部性
在一段时间内,程序访问的存储空间仅限于某个区域(这称为空间局部性),或者最近访问过的程序代码和数据很快会再次被访问(这称为时间局部性)。
程序执行的局部性允许程序局部装入
在较小的一段时间内,整个作业空间中只有某一局部模块的指令和数据会被执行和访问到。作业其它部分暂时不会访问到。
这就允许仅在内存保留当前需要运行的程序部分,而其它部分暂时留在外存。
3、实现虚拟存储器需要解决的问题
(1)主存辅存统一管理问题
(2)逻辑地址到物理地址的转换问题
(3)部分装入和部分对换问题
虚拟存储器的实现技术主要有
(1)请求分页式虚拟存储管理
(2)请求分段式虚拟存储管理
(3)请求段页式虚拟存储管理
二、请求分页虚拟存储管理
1、请求分页虚拟存储系统基本原理
在进程开始运行之前,装入全部页面集合中的一个或几个页面,进程运行过程中,访问的页面不在内存时,再装入所需页面;
若内存空间已满,而又需要装入新的页面时,则根据某种算法淘汰某个页面,以便装入新的页面。
2、请求分页系统的页表结构(略)
3、分页虚拟存储系统的硬件支撑
分页虚拟存储系统需要内存管理部件MMU。
MMU通常由一个或一组芯片组成,它接受虚拟地址(逻辑地址)作为输入,输出物理地址。
MMU的功能
①管理硬件页表寄存器,装入将要占用处理器的进程页表
②分解逻辑地址为页号和页内地址
③管理快表:查找快表、装入表目和清除表目
④访问页表
⑤当要访问的页面不在内存时发出缺页中断,页面访问越界时发出越界中断
⑥设置和检查页表中的引用位、修改位、有效位和保护权限位等各个特征位
缺页中断与普通中断的差异
(1)普通中断在两条指令之间才会响应;缺页中断涉及的指令在执行期间就需要响应缺页中断。
(2)当指令本身或者指令所处理的数据跨页时,在执行一条指令的过程中可能发生多次缺页中断。
4、请求分页的地址变换过程
进程开始执行并要访问某个虚拟地址时,内存管理部件MMU的工作如下
①MMU接受CPU传送过来的虚地址并分解为两部逻辑地址 分:页号和页内地址
②以页号为索引搜索快表
③如果命中快表,则立即送出物理块号(页框号),并与页内地址拼接形成物理地址,然后访问相应内存单元
④如果不命中快表,则以页号为索引搜索内存页表
⑤在页表中查找相应表项,如果其状态位指示该页已在 内存,则送出物理块号与页内地址拼接形成物理地址访问相应内存单元,同时要将该表项装入快表
⑥如果在页表中找到的相应表项,其状态位指示该页不在内存,则发出缺页中断,请求操作系统处理
⑦存储管理软件将所缺页面调入内存,修改页表
5、缺页中断处理过程
-
步1 挂起请求缺页的进程
-
步2 根据页号查外页表,找到该页存放的磁盘物理地址
-
步3 查看主存是否有空闲页框,如有则找出一个,修改主存管理表和相应页表项内容,转步6
-
步6 进行调页,把页面装入主存所分配的页框中,同时修改进程页表项
-
步7 返回进程断点,重新启动被中断的指令
-
步4 如主存中无空闲页框,则按替换算法选择淘汰页面,检查它曾被写过或修改过吗?若未则转步6;若是则转步5
-
步5 该淘汰页面被写过或修改过,则把它的内容写回磁盘原先位置
缺页中断处理过程总结
①查看内存是否有空闲物理块,如有则装入页面到空闲物理块,同时修改页表相应项以及内存分配表
②如果内存中没有空闲物理块,则按替换算法选择一个页面淘汰,若该页面被写过或修改过,则写回外存;
否则只简单淘汰该页面。淘汰页面之后要修改页表相应项,然后调入页面到淘汰页面释放的物理块中
6、页面装入策略和清除策略
页装入策略
决定何时把一个页面装入内存
主要有两种调入方式
-
请页式调入:需要访问程序和数据时,才把所需页面装入主存。 缺点:处理缺页中断和调页的系统开销较大, 每次仅调一页,磁盘I/O次数较多
-
预调式调入:由系统预测进程将要使用的页面,使用前预先 调入主存,每次调入若干页面,而不是仅调一页。 优点:一次调入多页能减少磁盘I/O启动次数,节省寻道和搜索时间
页清除策略:考虑何时把一个修改过的页面写回外存
主要有两种清除方式:
-
请页式清除:仅当一页选中被替换,且之前它又被修改过,才把这个页面写回辅存
-
预约式清除:对所有更改过的页面,在需要之前就把它们都写回外存
7、页框分配策略
页框分配策略
决定系统为每个进程分配多少个页框用于装载页面
分配页框时考虑的因素
分配给各个进程的内存越少
-
可以驻留内存的进程数就越多
-
系统找到就绪进程的可能性就越大
-
减少进程交换消耗的处理器时间
分配给进程的内存越少
-
进程缺页率就越高
-
频繁置换页面会降低系统效率
分配给进程的内存超过一定大小后
-
该进程的缺页率没有明显变化
页框分配策略主要有两种:固定分配(固定分配使进程在生命周期中保持固定数目的页框(即物理块)。进程创建时,根据进程类型和程序员的要求决定页框数。)和可变分配(进程分得的页框数可变。进程执行的某阶段缺页率较高,说明目前局部性较差,系统可多分些页框以降低缺页率,反之说明进程目前的局部性较好,可减少分给进程的页框数)
8、页面替换策略
为装入待访问的外存页面而选择某一内存页面用以置换的策略
-
局部替换(进程发生缺页时仅从该进程的页框中淘汰页面,以调入所缺页面)
-
全局替换(进程发生缺页时从系统中任一进程的页框中淘汰页面)
9、页框分配和替换组合策略
页框分配和替换的常用组合策略有三种
-
固定分配局部置换
-
可变分配全局置换(先为每个进程分配一定数目页框,系统保留若干空闲页框。 进程发生缺页中断时,从系统空闲页框中选一个给进程,缺页中断次数减少。 系统拥有的空闲页框耗尽时,从主存中选择任一进程的一页淘汰,这将使那个进程的缺页中断率上升)
-
可变分配局部置换(①新进程装入主存时,根据应用类型、程序要求,分配给一定数目页框 ②产生缺页中断时,从该进程驻留页面集 中选一个页面替换 ③不时重新评价进程的缺页率,增加或减少分配给进程的页框以改善系统性能)
10、缺页中断率
(1)缺页中断率
对于进程P的一个长度为A的页面访问序列,如果进程P在运行中发生缺页中断的次数为F,则f = F/A称为缺页中断率。
缺页中断率影响因素
①进程分得的主存页框数——页框数多则缺页中断率低,页框数少则缺页中断率高
②页面大小——页面大则缺页中断率低,页面小则缺页中断率高
③页面替换算法的优劣决定缺页率
④程序特性——程序局部性好,则缺页中断率低;否则缺页中断率高
(2)抖动(或者颠簸)
在请求分页虚拟存储管理系统中,刚被淘汰的页面立即又要访问,而调入不久即被淘汰,淘汰不久再被调入,如此反复,使得系统的页面调度非常频繁,以致大部分时间消耗在页面调度上,而不是执行计算任务,这种现象称为“抖动”(或者颠簸)。
11、固定分配局部页面替换算法
常见算法:
-
最佳页面淘汰算法(OPT)——调入一页而必须淘汰一个旧页时,所淘汰的页是以后不再访问的页或距现在最长时间后再访问的页。OPT可用于衡量各种具体算法的标准
-
先进先出页面淘汰算法(FIFO)——先进先出页面淘汰算法总是淘汰最先调入主存的那一页,或者说在主存中驻留时间最长的那一页(常驻的除外)。
-
最近最久未使用页面淘汰算法(LRU)——淘汰的页面是在最近一段时间里较久未被访问的那一页