操作系统随记

1 计算机系统概述

1.1 OS基本概念

1 定义

操作系统OS是指控制和管理整个计算机系统的硬件和软件资源,合理地组织、调度计算机的工作和资源分配;为用户和其他软件提供方便的接口和环境;操作系统是计算机系统中最基本的系统软件。

2 特征

并发、共享、虚拟、异步

并发:
并发是指两个或多个事件在同一时间间隔内发生;宏观上同时发生,微观上交替发生
并发性:两个或多个事件在同一时间间隔内发生。
并行性:两个或多个事件在同一时刻发生,需要硬件支持,如多流水线或多处理机硬件环境。

共享:
资源共享即共享,是指系统中的资源可供多个并发执行的进程使用;可分为互斥共享和同时共享。
临界资源:一段时间内只允许一个进程访问的资源
互斥共享:一段时间内只允许一个进程访问该资源;大多数物理设备都是互斥共享
同时共享:一段时间内允许多个进程同时访问该资源;这里的同时指宏观上

并发和共享是操作系统两个最基本的特征,两者互为存在条件
1.资源共享是以程序的并发为条件的,若系统不允许程序并发执行,则自然不存在资源共享问题
2.若系统不能对资源共享实施有效的管理,则必将影响到程序的并发执行,甚至根本无法并发执行

虚拟:
虚拟是指把一个物理上的实体变为若干个逻辑上的对应物。物理实体(前者)是实际存在的,而逻辑上对应物(后者)是用户感受到的
虚拟处理器:时分复用,让多道程序并发执行的方法,来分时使用一个处理器,虽然只有一个处理器,但它能同时为多个用户服务,使每个终端用户都感觉有一个中央处理器(CPU)在专门为它服务
虚拟存储器:通过空分复用技术,将一台机器的物理存储器变为虚拟存储器,以便从逻辑上扩充存储器的容量。当然,这时用户所感觉到的内存容量是虚的。
虚拟I/O设备:采用虚拟设备技术将一台物理I/O设备虚拟为多台逻辑上的I/O设备,并允许每个用户占用一台逻辑上的I/O设备,使原来仅允许在一段时间内由一个用户访问的设备(即临界资源)变为在一段时间内允许多个用户同时访问的共享设备。

异步:
在多道程序环境下,允许多个程序并发执行,但由于资源有限,进程的执行不是一贯到底的,而是走走停停,以不可预知的速度向前推进,这就是进程的异步性

3 功能

为了给多道程序提供良好的运行环境:处理机管理、存储器管理、设备管理、文件管理
为了方便用户使用,向提供接口:命令接口、程序接口
可用来扩充机器,以提供更方便的服务、更高的资源利用率

处理机管理:
即对进程的管理,包括进程控制、进程同步、进程通信、死锁处理、处理机调度等。

存储器管理:
方便程序运行、用户使用及提高内存的利用率,包括内存分配与回收、地址映射、内存保护与共享和内存扩充等功能。

文件管理:
计算机中的信息都是以文件的形式存在的,操作系统中负责文件管理的部分称为文件系统。
文件管理包括文件存储空间的管理、目录管理及文件读写管理和保护等。

设备管理:
设备管理的主要任务是完成用户的I/O请求,方便用户使用各种设备,并提高设备的利用率,主要包括缓冲管理、设备分配、设备处理和虚拟设备等功能。


命令接口:
用户利用这些操作命令来组织和控制作业的执行
联机命令接口:即交互式命令接口,适用于分时或实时系统。
脱机命令接口:即批处理命令接口,适用于批处理系统

程序接口:
程序接口由一组系统调用(也称广义指令)组成。是为编程人员提供的接口。普通用户不能直接使用程序接口,只能通过程序代码间接使用。
用户通过在程序中使用系统调用命令请求OS为其提供服务。系统调用命令又称广义指令。
GUl:图形化用户接口,用户可以使用形象的图形界面进行操作


对计算机资源的扩充:
在裸机上安装的操作系统,可以提供资源管理功能和方便用户的服务功能,将裸机改造成功能更强、使用更方便的机器。
通常把覆盖了软件的机器成为扩充机器,又称之为虚拟机。

1.2 发展历程

在这里插入图片描述

1.手工操作阶段(无操作系统)
程序的装入、允许、输出的结果都要人工干预
缺点是用户独占全机、CPU利用不充分、CPU与IO速度不匹配

2.批处理阶段(操作系统开始出现)
单道批处理系统:引入脱机输入输出技术,自动线、顺序性、单道性,缓解人机速度矛盾,但资源利用率还是低
多到批处理系统:多道程序设计技术操作系统开始出现,允许多个程序在CPU交替运行,多到、宏观并行、微观串行、间断性、共享性、制约性;主要解决如何分配处理器,多到程序的内存分配问题、IO设备如何分配,如何组织和存放大量的程序和数据,以方便用户使用并保证其安全性与一致性;资源利用率高,系统吞吐量大,但用户相应时间长,无人机交互能力

3.分时操作系统:
时间片轮转,每个用户都可以和计算机交互互不干扰
特点:同时性,交互性,独立性,及时性
缺点:无法处理及时任务

4.实时操作系统
能在某个时间限制内完成某些紧急任务不需要时间片排队,有软实时系统和硬实时系统
特点:及时性、可靠性

5.网络操作系统和分布式计算机系统
网络操作系统:把计算机网络中的各台计算机有机地结合起来,提供一种统一、经济而有效的使用各台计算机的方法,实现各台计算机之间数据的互相传送;网络中各种资源的共享,各台计算机之间的通信
分布式计算机系统:由多台计算机组成并满足下列条件的系统,主要特点是分布性和并行性

6.个人计算机操作系统
个人计算机操作系统是目前使用最广泛的操作系统,它广泛应用于文字处理、电子表格、游戏中。

引入多到程序设计的前提条件是有中断功能

通道技术是一种硬件技术

1.3 程序运行环境

1.3.1 处理器运行模式

操作系统内核程序:管理程序(内核程序)

用户编写程序:应用程序

特权指令:不允许用户直接使用的指令,如IO指令、关中断指令、内存清零指令

非特权指令:允许用户直接使用的指令,不能直接访问系统中的软硬件资源,仅限于访问用户的地址空间

CPU允许模式分为用户态(目态)、核心态(管态)

操作系统的内核包括:
1.时钟管理:
计时,通过时钟管理实现的进程切换
2.中断机制:
3.原语:
不能被打断,定义的直接方法是关中断
4.系统控制的数据结构及处理:
作业控制块、PCB、设备控制块、各类链表、消息队列、缓冲区等
进程管理:
存储器管理:
设备管理:

1.3.2 中断和异常的概念

在这里插入图片描述

故障:执行指令引起的异常,如非法操作码、缺页故障、除数为0、运算溢出等

自陷:实现安排的异常事件,让用户去转到核心态,如条件陷阱指令

终止:硬件故障

外中断:硬件中断

1.3.3 系统调用

系统调用是指用户在程序中调用操作系统提供的一些子功能

系统调用的功能:
设备管理:设备的启动,请求或释放
文件管理:读写删
进程控制:创建、销毁、阻塞、唤醒
进程通信:进程间消息或信号传递
内存管理:分配回收

系统调用的处理需要在核心态完成

中断是操作系用必须提供的功能

时钟中断是外部中断

库函数方便调试和替换,系统调用不方便调试,不能替换

1.4 操作系统结构

在这里插入图片描述
在这里插入图片描述

1.分层法
每层只能调用紧邻他的底层的功能和服务(单向)
优点:
便于调试和验证,简化系统的设计和实现
易于扩充和维护,不影响其他层
缺点:
合理定义各层比较困难
效率较差

2.模块化
将操作按功能划分为具有一定独立性的模块,规定好各模块的接口,这种方法称为模块-接口法
内聚性:模块内各部分联系紧密,内聚性越高,模块独立性越好
耦合性:模块间相互联系和影响的程序,耦合性越低,模块独立性越好
优点:
提高操作系统设计的正确性、可理解性、可维护性
增强可使用性,加快开发过程
缺点:
模块间的接口规定很难满足实际需求
各模块设计者齐头并进,每个决定无法建立在上一个已验证的正确决定的基础上,因此无法找到一个可靠的决定顺序

从操作系统的内核架构,可分为宏内核和微内核
3.宏内核
又称大内核或单内核,将操作系统的主要功能模块都作为一个整体运行在核心态,提供高性能服务
优点:高性能
缺点:内核代码庞大,结构混乱,难以维护
应用:windows、linux、ios、macOS;广泛吸收微内核优点进行改进

4.微内核
基本概念:将内核中最基本的功能保留在内核,将那些不需要在核心态执行的功能移到用户态,降低内核设计的复杂性。而移出内核的操作系统代码根据根据分层原则被划分为若干服务程序,相互独立运行,借助微内核通信。
微内核架构=微内核+多个服务器
微内核:与硬件处理紧密相关的部分;一些基本功能;客户和服务区之间的通信
服务器(进程):提供对进程线程进行管理的进程线程服务器、提供虚拟存储器管理功能的虚拟存储器服务器
客户和服务器之间借助微内核提供的消息传递机制来实现交互
微内核基本功能:进程线程管理;低级存储器管理,如依赖于硬件实现的页表机制和内存变换机制;中断和陷入处理。微内核只将这三个功能中属于机制的很小一部分放入微内核
特点:
扩展性和灵活性
可靠性和安全性:某个模块崩溃不会使整个系统崩溃
可移植性
分布式计算:采用消息传递机制,很好的支持分布式系统和网络系统
缺点:
需要频繁地在核心态和用户态之间切换,性能低
应用:鸿蒙OS、实时、工业、航空和军事应用

5.外核
内核负责进程调度、进程通信等功能;外核在内核态运行,负责为用户进程分配未经抽象的硬件资源,且由外核负责保证资源使用安全
为虚拟机分配资源,并检查使用这些资源的企图,以确保没有机器会使用他人的资源。每个用户层的虚拟机可以运行自己的操作系统,但限制只能使用已经申请并且获得分配的那部分资源。
优点:
核可直接给用户进程分配“不虚拟、不抽象的硬件资源,使用户进程可以更灵活的使用硬件资源
减少了虚拟硬件资源的“映射层",提升效率
缺点:
降低了系统的一致性,使系统变得复杂

1.5 操作系统引导

在这里插入图片描述

操作系统引导是指计算机利用CPU运行特定程序,通过程序识别硬盘,识别硬盘分区,识别硬盘上的操作系统,最后通过程序启动操作系统

BIOS 程序(Basic Input/Output System):BIOS 是固化在主板上的基本输入输出系统,是计算机启动第一个运行的软件,存放在ROM中。它会进行硬件初始化和自检,然后查找引导程序并执行。

引导程序(Boot):引导程序是存储在主存ROM中的一段小程序,它的作用是将操作系统的内核文件从硬盘中读取到内存中,并跳转到内核入口点开始执行。

主引导记录(MBR):MBR是硬盘的主引导记录,位于硬盘的第一个扇区。它包含了磁盘引导程序和分区表。该引导程序会找到活动分区并读取其分区引导记录,完成硬盘的引导。

分区引导记录(PBR):PBR是分区引导记录,位于每个分区的第一个扇区。PBR中包含了一个引导程序,可以寻找并激活分区根目录下的启动管理器,完成分区的引导过程。

1.激活CPU:激活的CPU读取ROM中的boot程序,将指令寄存器置为BIOS的第一条指令,开始执行BIOS
2.硬件自检
3.加载带有操作系统的硬盘
4,加载主引导记录
5.扫描硬盘分区表
6.加载分区引导记录
7.加载启动管理器
8.加载操作系统

1.6 虚拟机

使用虚拟化技术,将一台物理机器虚拟化为多台虚拟机器VM,每个虚拟机器都可以独立运行一个操作系统。

在这里插入图片描述

第一类虚拟机:

第一类虚拟机管理程序就像一个操作系统,他是唯一一个运行在最高特权级的程序,在裸机上运行并具备多道程序功能。虚拟机管理程序向上提供若干虚拟机,这些虚拟机是逻辑硬件的复制品,可以在虚拟机上运行不同的操作系统。

虚拟内核态:虚拟机是用户态,而虚拟机上的操作系统认为自己运行在内核态;真正内核态的指令交由虚拟机管理程序执行。

第二类虚拟机:

依赖于windows、linux等操作系统分配和调度资源,很像一个普通进程,如VMware Workstation。

对于第二类虚拟机管理程序,运行在底层硬件上的操作系统称为宿主操作系统;运行在虚拟机管理程序上的操作系统称为客户操作系统。

首次启动时,第二类虚拟机管理程序像一台刚启动的计算机那样运转,期望找到的驱动器可以是虚拟设备。然后将操作系统安装到虚拟磁盘上(其实只是宿主操作系统中的一个文件)。客户操作系统安装完成后,就能启动并运行。

第一类VMM第二类VMM
对物理资源的控制权直接运行在硬件之上,能直接控制和分配物理资源运行在Host OS之上,依赖于Host OS为其分配物理资源
资源分配方式在安装Guest OS时,VMM要在原本的硬盘上自行分配存储空间,类似于"外核“的分配方式,分配未经抽象的物理硬件GuestOs拥有自己的虚拟磁盘,该盘实际上是HostOs文件系统中的一个大文件。GuestOs分配到的内存是虚拟内存
性能性能更好性能更差,需要Host Os作为"中介”
可支持的虚拟机数量更多,不需要和Host OS竞争资源,相同的硬件资源可以支持更多的虚拟机更少,Host Os本身需要使用物理资源,Host OS上运行的其他进程也需要物理资源
虚拟机的可迁移性更差更好,只需导出虚拟机镜像文件即可迁移到另一台Host Os上,商业化应用更广泛
运行模式第一类VMM运行在最高特权级(Ring 0),可以执行最高特权的指令。第二类VMM部分运行在用户态、部分运行在内核态。GuestOs发出的系统调用会被VMM截获,并转化为VMM对Hostos的系统调用

2 进程和线程

进程和线程:
基本概念;进程线程的状态与转换
线程的实现:内核支持的线程,线程库支持的线程
进程和线程的组织和控制
进程间通信:共享内存,消息传递,管道

CPU调度与上下文切换:
调度的基本概念;调度的目标
调度的实现:调度器/调度程序,调度的时机和方式(抢占式/非抢占式),闲逛进程,内核级线程与用户级线程调度
典型调度算法:先来先服务,短作业,时间片轮转,优先级调度,高响应比优先,多级队列,多级反馈队列
上下文切换机制

同步与互斥:
基本概念
实现方法:软件,硬件
锁:信号量;条件变量
经典同步问题:生产者-消费之;读者-写者;哲学家进餐

死锁:
基本概念;预防死锁
死锁避免;死锁检测和解除

2.1 进程与线程

2.1.1 概念和特征

概念:
进程控制块PCB:
进程:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位

特征:
动态性(最基本的特征)、并发性、独立性、异步性(需要进程同步机制)

2.1.2 进程的组成

在这里插入图片描述

进程控制块PCB:
进程创建时新建一个PCB,常驻内存,是进程实体的一部分,是进程存在的唯一标志;系统通过PCB了解该进程状态和优先级
进程标识符:每个进程一个唯一的标识号
用户标识符:进程所归属的用户,主要为共享和保护服务
进程当前状态:描述进程状态信息,是CPU分配调度的依据
进程优先级:
资源分配清单:有关内存空间或虚拟地址空间的状况,所打开的文件列表和所使用的输入输出设备信息
处理机相关信息:CPU上下文,主要指CPU各存储器的值,保存断点这些

程序段:被进程调度程序调度到CPU执行的程序代码段

数据段:可以是进程对应加工处理的原始数据,也可以是程序执行时的中间或最终结果。

进程的组织方式有链接和索引

2.1.3 进程的状态和转换

在这里插入图片描述

运行态:进程在CPU上运行,每一时刻只有一个进程在允许
就绪态:进程获得除CPU外的一切资源,等待cpu调度,系统中可以有一个或多个就绪队列
阻塞态:等待除CPU外的某些资源,可以有一个或多个阻塞队列
创建态:正在创建,首先申请一个空白的PCB,向PCB中写入控制和管理的信息,并分配资源,再插入就绪状态
终止态:进程正在从系统中消失,可能是正常结束或其他原因,需要释放资源和回收

从运行态变为阻塞态是主动行为,从阻塞态变为就绪态是被动行为,需要其他相关进程的协助

2.1.4 进程控制

一般将进程控制用的程序段称为原语,原语的特点是不允许中断,是一个不可分割的单位

进程的创建
父进程和子进程:父进程可以创建子进程,子进程可以继承父进程所拥有的资源;当子进程被撤销时,应当将从父进程获得的资源归还给父进程;父进程撤销时会撤销所有子进程。
终端用户登录系统、作业调度、系统提供服务、用户程序的应用请求等都会引起进程的创建
创建原语:
1.为进程分配一个唯一的进程标识号,并申请一个空白的PCB(PCB是有限的),若PCB申请失败,则进程创建失败
2.为进程分配所需的资源,如内存、文件、IO设备和CPU时间,从操作系统或父进程获得;如果资源不足,会一直处于创建态等待资源,而不是创建失败
3.初始化PCB,主要包括初始化标志信息、CPU状态信息和控制信息,以及设置进程优先级
4.插入进程就绪队列
进程的终止
引起进程终止的事件有:
1.正常结束,表示进程的任务已完成并准备退出运行
2.异常结束,表示进程在运行时,发生某种异常事件,如存储器越界、保护错、非法指令、特权指令错、允许超时、算术运算错、IO故障
3.外界干预,指进程应外界的请求而终止运行,如操作员或系统干预、父进程请求和父进程终止
终止原语:
1.根据进程标识符,找到对应PCB,从中读出进程的状态
2.若进程处于运行态,立即终止并将CPU资源分配给其他进程
3.若还有子进程,通常将子进程终止
4.将该进程拥有的全部资源,归还给操作系统或父进程
5.将PCB从所在的队列(链表)删除
进程的阻塞
正在执行的进程等待资源,如请求系统资源失败、等待某种操作的完成、新数据尚未达到或无新任务可做等;将自己由运行态变为阻塞态,是一种主动行为、阻塞原语:
1.找到进程标识号PID对应的PCB
2.该进程在运行态,保护现场,将其状态转为阻塞态,停止运行
3.将PCB插入相应事件的等待队列,将CPU资源调度给其他进程
进程的唤醒
当阻塞进程获得所需要的资源时,调用唤醒原语
唤醒原语:
1.在该事件的等待队列中找到相应进程的PCB
2.将其从等待队列中移除,状态改为就绪态
3.将PCB插入就绪队列,等待调度

block原语和wakeup原语是一对作用刚好相反的原语,必须成对使用;如果在某个进程调用了block原语,必须在与之合作或相关的进程安排一条相应的wakeup原语,否则,阻塞进程将永远阻塞不能被唤醒

2.1.5 进程的通信

进程之间的信息交换

低级通信:PV操作方式、

高级通信:共享存储、消息队列、管道

共享存储

在通信的进程之间存在一块可直接访问的共享空间,通过对这片空间进行读写操作实现信息交换。读写操作时,需要使用同步互斥工具PV操作

低级方式共享:基于数据结构的共享

高级方式共享:基于存储区的共享

操作系统只负责提供可共享使用的存储空间和同步互斥的工具,数据交换又用户自己安排读写指令完成

消息队列

进程之间交换信息以格式化的消息为单位,进程通过操作系统提供的发送消息和接收消息两个原语进行数据交换;是目前应用最广泛的进程间通信机制。例如微内核操作系统中,微内核与服务器之间的通信就采用了消息传递机制,该机制很好地支持多CPU系统、分布式系统和计算机网络,成为这些领域最主要的通信工具。

直接通信方式:进程直接给进程发送消息,并将让挂在接收进程的消息缓冲队列上,接收进程从消息缓冲队列取得消息

间接通信方式:通过中间实体信箱完成,广泛应用于计算机网络中

管道

管道是一个特殊的共享文件,又称pipe文件,数据在管道中先进先出,管道允许两个进程按生产者-消费者的方式进行通信,只要管道不满,写进程就可以从一端写入,只要管道非空,读进程就可从另一端读出。

为协调通信,管道必须提供三方面的协调能力:1、互斥,读写互斥;2、同步,写满后写进程阻塞,空时读进程阻塞;3、确定对方的存在

管道本质上也是一种文件,管道克服使用文件通信的两个问题:

1.限制管道的大小,而不像文件可以无限增长;linux中管道大小为4kb;管道满时写进程会阻塞

2.管道空时,read()进程阻塞

管道只能由创建进程访问,子进程可继承父进程管道,可用它来与父进程通信

管道只允许单向通信,若需要双向,需要定义两个管道

2.1.6 线程

基本概念:

进程:为了更好的使多道程序并发执行,提高资源利用率和系统吞吐量
线程:减小程序并发执行时所付出的时空开销,提高操作系统的并发性能
线程是轻量级的进程,是CPU执行的基本单元,由线程ID、程序计数器、寄存器集合和堆栈组成
线程是进程中一个实体,是不拥有自己的资源,可以共享进程的全部资源

线程和进程的比较:

1.调度:同一个进程下的线程调度是不会引起进程切换
2.并发性:除了进程,线程也能并发执行,提高系统的利用率和吞吐量
3.拥有资源:进程是系统中拥有资源的基本单位,而线程不拥有系统资源
4.独立性:同一进程中的线程共享地址空间和资源,不同线程中的进程相互独立
5.系统开销:线程切换开销小
6.支持多处理器系统:进程中的多个线程可分配到多个CPU上执行

线程的属性:

1.线程是一个轻型实体,不拥有系统资源,每个线程都应拥有唯一的标识符和线程控制块,记录线程执行的寄存器和栈等现场状态
2.不同的线程可以执行相同的程序,一个服务程序被不同的用户调用时,系统会将他们创建成不同的线程
3.线程是CPU调度的基本单位,多个线程可以并发执行
4.线程的生命周期会经历阻塞态、就绪态和运行态等

线程可以提高系统并发性理解:线程切换时可能有进程切换,也可能没有,平均开销变小了

线程的状态与转换:

执行态:正在运行
就绪态:只差CPU
阻塞态:

线程的组织与控制:

1.线程控制块PCB:
线程标识符;一组寄存器,包括程序计数器、状态寄存器和通用寄存器;线程运行状态;优先级;线程专有存储区,线程切换时用于保存现场;堆栈指针,用于过程调用时保存局部变量和返回地址
2.线程的创建:
操作系统中有用于创建和终止线程的函数
用户启动程序时,通常有一个称为初始化线程的线程正在执行,用于创建新线程,需要调用一个线程创建函数,提供相应的参数,执行函数后,返回一个线程标识符
3.线程的终止:
调用相应的函数来终止线程
线程被终止后并不立即释放他的所有资源,只有当进程中的其他线程执行了分离函数后,被终止的线程才与资源分离,此时资源才能被其他线程调用
被终止但尚未释放资源的线程仍可被其他线程调用,以使被终止的线程重新恢复运行

线程的实现方式:

在这里插入图片描述

用户级线程ULT:有关线程管理的任何工作都由应用程序在用户空间中完成,内核意识不到线程的存在,依旧以进程为切换单位
优点:线程切换不需要内核,节省切换开销;可以自定义调用算法;
缺点:阻塞时会全部阻塞;不能发挥多CPU优势

内核级线程KLT:
每个内核级线程设置一个TCB
优点:能发挥多CPU优势;一个线程被阻塞,其他线程可正常运行
缺点:线程切换要转到内核态

组合方式:

线程库是为程序员提供创建和管理线程的API
1.没有内核支持:所有代码和数据结构都位于用户空间
2.有内核支持:代码和数据结构位于内核,调用一个API函数通常会导致对内核的系统调用

在这里插入图片描述

多线程模型:

1.多对一:多个用户级线程映射到一个内核级线程,一个进程--一个内核级线程,线程的调度和管理在用户空间完成;仅当需要线程需要访问内核时才进行映射,每次只允许一个线程进行映射
优点:管理在用户空间,效率高
缺点:一个线程访问内核阻塞时整个进程阻塞;多线程不能同时在多个CPU上运行

2.一对一:每个用户级线程映射到一个内核级线程,线程切换由内核完成
优点:一个线程阻塞后,允许调度另一个线程,并发能力强
缺点:没创建一个用户线程,需要相应一个内核线程,开销大

3.n对m:n个用户级线程映射到m个内核级线程,n>=m
拥有以上两种情况的综合优点

2.2 CPU调度

2.2.1 调度的概念

多道程序系统中,进程的数量多于CPU的数量,CPU调度是对CPU进行分配,按照一定的算法从就绪队列中选择一个进程分配CPU。

CPU调度是多道程序操作系统的基础,是操作系统设计的核心。

三级调度:

在这里插入图片描述

高级调度(作业调度):从外存的后备队列中选择一个或多个进入内存,为他们建立进程,送到就绪队列。每个作业只调入一次,调出一次。多道批处理系统大多配有作业调度,而其他系统中通常不需要配置作业调度。

中级调度(内存调度):为了提高内存利用率和系统吞吐量,将暂时不能运行的进程调至外存等待,称为挂起态;等有了运行条件和内存,再将进程调入内存的就绪队列。中级调度实际上是存储器管理中的对换功能。

低级调度(进程调度):就绪队列中选择一个进程分配CPU,频率最高。

1.作业调度为进程做活动准备,使进程能正常活动起来
2.中级调度挂起暂时不能运行的进程,处于作业调度和进程调度之间
3.作业调度最少,中级调度第二,进程调度频率最高
4.进程调度最基本,不可或缺。

2.2.2 调度的实现

1.调度程序(调度器)

用于调度和分派CPU的组件:

在这里插入图片描述

排队器:将系统中所有就绪进程按一定策略排成一个或多个就绪队列;每当有一个进程转变为就绪态时,排队器便将它插入相应的就绪队列。

分派器:依据调度程序所选的进程,将其从就绪队列中取出,将CPU分配给新进程

上下文切换器:
第一对切换:将当前进程的上下文保存到其PCB,在装入分派程序的上下文
第二对切换:新选程序的现场信息加入CPU寄存器

进程上下文:CPU的所有寄存器的值(现场信息)、进程的状态和控制信息以及堆栈中的内容。

2.调度的时机、切换与过程
调度和切换的时机:
1.创建新进程后,需要选择一个上处理机
2.进程正常结束或异常终止后,需要从就绪队列选择一个进程运行,如果没有就绪进程,就运行闲逛进程
3.进程被阻塞时
4.当io设备完成后,发出IO中断,让原本等待IO的进程从阻塞态变为就绪态,此时需要决定是新的进程投入运行还是让中断运行的进程继续执行

不能切换和调度的情况:
1.处理中断时
2.需要完全屏蔽中断的原子操作,如加锁、解锁、中断现场保护、恢复源自操作;原子操作时需要屏蔽中断
3.进程调度的方式

非抢占调度方式,又称非剥夺方式

抢占调度方式,又称剥夺方式

4.闲逛进程

Idel process,PID为0,不需要CPU之外的资源,不会被阻塞

5.两种线程调度
1.用户级线程调度:内核控制进程,由进程中的调度程序调度线程
2.内核级线程调度:

2.2.3 调度的目标

CPU利用率:CPU有效工作时间 / (CPU有效工作时间+CPU空闲等待时间)

系统吞吐量:单位时间内CPU完成作业的数量

周转时间:作业等待、在就绪队列中排队、在CPU上运行和IO操作花费时间的总和

周转时间=作业完成时间-作业提交时间

平均周转时间:

带权周转时间:作业周转时间 / 作业运行时间

等待时间:进程等待CPU的时间之和

响应时间:用户提交作业到首次产生响应所用的时间

2.2.4 进程切换

上下文切换:CPU从一个进程切换到另一个进程需要保存当前进程状态并恢复另一个进程的状态;进程上下文采用进程PCB表示,包括CPU寄存器的值、进程状态和内存管理器等。
1.挂起一个进程,将CPU上下文保存到PCB,包括程序计数器和其他寄存器
2.将进程移入就绪或阻塞队列
3.选择另一个进程执行,并更新其PCB
4.恢复新进程的CPU上下文
5.跳转到新进程PCB中程序计数器所指的位置执行

模式切换:用户态和内核态的切换,CPU逻辑上可能还在执行同一个进程

上下文切换只能发生在内核态
调度是一种决策行为,切换是一种执行行为;一般来说,先有资源的调度,再有进程的切换

2.2.5 典型调度算法

先来先服务FCFS
作业调度,进程调度
算法简单,但效率低;对长作业比较有利,对短作业不利;有利于CPU繁忙型作业,不利于IO繁忙型作业
短作业优先SJF、短进程优先SPF
缺点:对长作业不利,会产生饥饿现象
可以算是抢占式,又称最短剩余时间优先算法
!!短作业优先是平均等待时间,平均周转时间最优的
高响应比优先调度算法
主要用于作业调度,是对FCFS和SJF的一种综合平衡
响应比 = (等到时间+要求服务时间) / 要求服务时间
1.等到时间相同时,要求服务时间短的优先级高,类似于短作业优先
2.要求服务时间相同时,等待时间长的优先级高,类似与FCFS
3.对于长作业,响应比随时间的增长而优先级增加,克服饥饿现象
优先级调度算法
作业调度、进程调度
抢占式优先级调度、非抢占式优先级调度
静态优先级调度:优先级在创建进程时确定;简单易行,系统开销小,不够精确
动态优先级调度:创建进程的优先级可随时间的改变而增加
系统进程>用户进程
交互性进程>非交互性进程 前台进程>后台进程
IO型进程>计算型进程 频繁使用IO设备的进程优先级更高,有利于提升系统的效率
时间片轮转RR
主要适用于分时系统,所有就绪进程按FCFS排成一个就绪队列,每个一个时间片产生一次时钟中断,在时间片内未完成的进程将完成调度,重新回到就绪队列队尾
如果一个时间片未结束进程就运行完成,立刻完成调度
时间片大小对进程影响很大,时间片足够大时,时间片轮转算法会退化为FCFS
多级队列调度算法
系统设置多个就绪队列,每个就绪队列可以采用不同的调度算法
可以将每一个就绪队列分配到相应的CPU
多级反馈队列调度算法

综合时间片轮转调度算法和优先级调度算法

多个队列,每个队列都采用FCFS;第一级别的时间片最短,第二级别的时间片比第一级别增加一倍,以此类推;只有当前面队列都为空时才会调度下一级别的队列;每个进程时间片走完还没执行完时,进入下一级队列

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.3 同步和互斥

2.3.1 同步和互斥的基本概念

临界资源:一次仅允许一个进程使用的资源称为临界资源;许多物理设备都属于临界资源:打印机

资源访问过程:
1.进入区:检查是否可以进入临界区,设置正在访问临界区的标志,阻止其他进程进入临界区
2.临界区:访问邻接资源的那段代码
3.退出区:将正在访问临界区的标志清除
4.剩余区:剩余部分

同步:直接制约关系;有一定的先后顺序
互斥:间接制约关系;空闲让进、忙则等待、有限等待、让权等待

2.3.2 实现临界区互斥的基本方法

软件实现方法

在进入区检查能否正常进入,如果有进程在临界区,则在进入区循环等待;进程离开临界区后则在退出区修改标志。

1.单标志法(违背空闲让进)

两个进程交替进入临界区

int turn=0;//表示那个进程可以进入临界区

p0:{
	while(turn!=0);
	临界区;
	turn=1;
	剩余区;
}

p1:{
	while(turn!=1);
	临界区;
	turn=0;
	剩余区;
}
2.双标志先检查(违背忙则等待)
bool flag[2]; //是否想进入临界区
flag[0] = false;
flag[1] = false;

p0:{
	while(flag[1]);
	flag[0]=true;
	临界区;
	flag[0]=false;
	剩余区;
}

p1:{
	while(flag[0]);
	flag[1]=true;
	临界区;
	flag[1]=false;
	剩余区;
}
3.双标识后检查(违背空闲让进,有限等待)饥饿
bool flag[2]; //是否想进入临界区
flag[0] = false;
flag[1] = false;
p0:{
	flag[0]=true;
	while(flag[1]);
	临界区;
	flag[0]=false;
	剩余区;
}

p1:{
	flag[1]=true;
	while(flag[0]);
	临界区;
	flag[1]=false;
	剩余区;
}
4.Peterson算法(违背让权等待,可能忙等)
bool flag[2];  //表示意愿
int turn = 0;  //表示哪个先进

//主动争取;主动谦让;检查对方是否想使用且最后是不是自己谦让
P0:{
	flag[0] = true;
	turn = 1;
	while(flag[1] && turn==1);
	临界区;
	flag[0] = false;
	剩余区;
}

P1:{
	flag[1] = true;
	turn = 0;
	while(flag[0] && turn==0);
	临界区;
	flag[1] = false;
	剩余区;
}
硬件实现方法

计算机提供了特殊的硬件指令,允许对一个字的内容进行检测和修正,或对两个字的内容进行交换

1.中断屏蔽

不适合多处理器系统

2.TestAndSet

不能让权等待

//共享变量lock表示当前临界区是否被加锁
bool TestAndSet(bool *lock){
	bool old;
	old = *lock;
	*lock = true; //无论之前是否加锁,都将lock设置为true
	return old;  // 返回原来的值
}

先检查lock,为false时进入;为true时循环等待
//使用TSL实现互斥的算法逻辑
while(TestAndSet(&lock));
临界区;
lock = false;
剩余区;
3.Swap

会占用CPU,不能让权等待

Swap(bool *a,bool *b);

bool old=true;
while(old == true)
	Swap(&lock,&old);
临界区;
lock=false;
剩余区;

2.3.3 互斥锁

进入临界区获得锁acquire(),退出临界区释放锁release();原子操作,由硬件完成;布尔变量available代表互斥锁;用于解决临界区的互斥功能

acquire(){
	while(!available);
	avilable = false; //获得锁
}

release(){
	available = true;
}

2.3.4 信号量

未遵循让权等待

整型信号量:
//两个标准原语
wait(S) == P
signal(S) == V

int S=1;
void wait(int S){
	while(S<=0);
	S=S-1;
}
void signal(int S){
	S=S+1;
}
记录型信号量:
typedef struct{
	int value;
	struct process *L;
}semaphore;

void wait(semaphore S){
	S.value--;
	if(S.value<0){
		block(S.L);
	}
}

void signal(semaphore S){
	s.value++;
	if(S.value<=0){
		wakeup(S.L);
	}
}
信号量实现互斥:
semaphore mutex=1;
p1(){
	P(mutex);
	临界区
	V(mutex);
}

信号量实现同步:
semaphore s=0;
p1(){
	...
	...
	V(s);
	...
}
p2(){
	P(s);
	...
	...
}

2.3.5 经典同步问题

生产者-消费者

在这里插入图片描述

多生产者多消费者

在这里插入图片描述

读者写者

互斥关系:写进程-写进程、写进程-读进程

有缺陷:

在这里插入图片描述

写优先:

在这里插入图片描述

哲学家进餐问题:

在这里插入图片描述

吸烟者问题:

在这里插入图片描述

2.3.6 管程

进程同步工具

1.定义

利用共享数据结构抽象的表示系统中的共享资源,将对该数据结构实施的操作定义为一组过程;统一管理对共享资源的访问,确保每次仅有一个进程使用共享资源

这个代表共享资源的数据结构,对该数据结构实施操作的一组过程所组成的资源管理程序,称为管程。

管程定义了一个数据结构和一组实现进程并发的操作。

组成:管程的名称;局部于管程内部共享数据结构的说明;对该数据结构进行操作的一组过程或函数;对共享数据结构设置初始值的语句

monitor Demo{//定义一个名称为"Demo"的管程

    //定义共享数据结构,对应系统中的某种共享资源
    共享数据结构 S;
    
    condition x;	//定义一个条件变量x
    
    //对共享数据结构初始化的语句
    init_code(){
        S=5;		//初始资源数等于5
    }
    //过程1:申请一个资源
    take_away(){
    	if(S<0){
    		//资源不够,在条件变量x上阻塞等待
    		x.wait();
    	}else{
    		对共享数据结构x的一系列处理;
            s--;		//可用资源-1
            ...
    	}
       

    }
    //过程2:归还一个资源
    give_back(){
        对共享数据结构x的一系列处理;
        s++;		//可用资源+1
        if(有进程在等待)x.signal();	//唤醒一个阻塞进程
    }
}

2.条件变量

当一个进程进入管程后被阻塞,直到阻塞原因被解除前,其他进程不能进入管程。将阻塞原因定义为条件变量condition;通常管程中可以设置多个条件变量,多个等待队列,对条件变量只能有wait和signal两种操作。

x.wait:将自己插入x条件的等待队列,并释放管程,其他进程可以使用

x.signal:唤醒一个进程

条件变量没有值,只能唤醒和阻塞进程,而信号量有值

2.4 死锁

2.4.1 死锁的概念

在并发环境下,各进程因竞争资源而造成一种互相等待对方手里的资源,导致各进程都阻塞。

死锁、饥饿、死循环

死锁、饥饿、死循环:
饥饿:长时间没有等待到资源分配

产生原因:对系统资源的竞争、进程推进顺序非法、信号量使用不当

产生必要条件:互斥条件、不剥夺条件、请求并保持条件、循环等待条件

只要有一个条件未满足,死锁就不会发生

处理策略:死锁预防、避免死锁、死锁的检测及解除

死锁预防:破坏死锁产生的必要条件
避免死锁:资源动态分配过程中,用某种方法防止系统进入不安全状态
死锁的检测与解除:允许死锁,死锁产生后采取措施解除死锁
资源分配策略各种可能模式主要优点主要缺点
死锁预防保守,宁可资源闲置一次请求所有资源,资源剥夺,资源按序分配适用于突发式处理的进程,不必进行剥夺效率低,进程初始化时间延长;剥夺次数过多;不便灵活申请新资源
死锁避免是“预防”和“检测”的折中(在运行时判断是否可能死锁)寻找可能的安全允许顺序不必进行剥夺必须知道将来的资源需求;进程不能被长时间阻塞
死锁检测宽松,只要允许就分配资源定期检查死锁是否已经发生不延长进程初始化时间,允许对死锁进行现场处理通过剥夺解除死锁,造成损失

2.4.2 死锁的预防

破坏互斥条件:互斥改为允许共享

破坏不剥夺条件:申请资源得不到时,主动释放占有资源;申请资源被其他进程占用时,由OS协助剥夺

破坏请求和保持条件:静态分配,运行前一次性申请全部资源;申请一部分先运行,释放部分资源后才可继续申请

破坏循环等待条件:顺序资源分配法限制申请资源的顺序

2.4.3 死锁的避免

在资源动态分配过程中,防止系统进入不安全状态,以避免发生死锁;每一次的资源分配之前先分析

1.系统安全序列

安全序列:按照这种序列分配资源,则每个进程都能顺利完成

安全状态:系统如果存在安全序列,则处于安全状态,安全状态可能有多个

不安全状态:不存在安全序列

死锁一定是不安全状态,不安全状态不一定是死锁;安全状态一定不会发生死锁

2.银行家算法

分配资源前,预先判断这次分配是否会导致系统进入不安全状态

1.可利用资源向量:Available(一维数据)

2.最大需求矩阵max:n*m矩阵,每个进程对每类资源的最大需求

3.分配矩阵Allocation:n*m矩阵,每个进程已分配到每类资源的数量

4.需求矩阵Need:n*m矩阵,每个进程还需要多少资源

在这里插入图片描述

在这里插入图片描述

2.4.4 死锁检测和解除

1.资源分配图

圆–进程,框–一类资源,框中的一个圆–一个资源;请求边;分配边

2.死锁定理

化简资源分配图检测系统状态是否为死锁状态

消去所有边

用死锁定理化简后,还有边相连的那些进程就是死锁进程

3.死锁解除

资源剥夺法:挂起某些死锁进程,抢占他的资源,将这些资源分配给其他死锁进程

撤销进程法:撤销进程并剥夺资源,简单代价大

进程回退法:让一个或多个死锁进程回退到足以避免死锁的地步,资源释放资源而不是被剥夺

3 内存管理

3.1 内存管理基础

内存管理概念:逻辑地址与物理地址空间、地址变换、内存共享、内存保护、内存分配与回收

连续分配管理方式:页面管理、段式管理、段页式管理

3.1.1 内存管理的基本原理和要求

内存管理:操作系统对内存的划分和动态分配

主要功能:内存空间的分配和回收、扩充(虚拟内存技术和自动覆盖技术)、地址转换、内存保护、内存共享

程序链接装入
编译:高级语言翻译成机器语言;形成若干目标模块
链接:把编译后形成的一组目标模块及他们所需要的库函数链接在一起,形成一个完整的装入模块;完整逻辑地址
装入:由装入程序将装入模块装入内存运行

在这里插入图片描述

静态链接:程序运行之前,先将各模块及他们所需的库函数连接成一个完整的可执行文件,之后不再拆开

装入时动态链接:将各模块装入内存时,边装入边链接

运行时动态链接:在程序执行中需要该目标模块时,才进行链接;便于修改和更新,便于实现对目标模块的共享

绝对装入:在编译和链接后,得到的装入模块指定直接使用了绝对地址;只适用单道程序环境

可重定位装入:装入时对地址进行重地位,即将逻辑地址变换为物理地址,地址变换是在装入时一次完成的;为静态重定位,装入时分配完整内存

动态运行时装入:模块装入内存时依旧使用的是逻辑地址,等待程序要运行时才转为物理地址,需要一个重定位寄存器的支持;可以将程序分配到不连续的空间,只需装入一部分就可以运行,运行期间动态分配内存,便于实现共享,允许程序在内存中发生移动

!链接是形成完整装入模块与逻辑地址,但逻辑地址到物理地址的转换是重定位而不是装入

逻辑地址、物理地址

逻辑地址到物理地址的转换称为地址重定位

操作系统通过内存管理部件MMU将使用的逻辑地址转换为物理地址

进程的内存映像

当一个程序调入内存运行时,就构成进程的内存映像

代码段:程序的二进制代码,只读,可共享
数据段:程序运行时加工处理的对象,包括全局变量和静态变量
进程控制块PCB:存放在系统区
堆:存放动态分配的变量,通过malloc函数动态向高地址分配空间
栈:实现函数调用,从高地址往低地址方向增长

代码段和程序段在程序调入内存时就指定了大小,而堆栈可以动态调整

在这里插入图片描述

共享库用来存放进程用到的共享函数库代码,如printf函数等
在只读代码段中,.init是程序初始化时调用的_init函数;.text是用户程序的机器代码;.rodata是只读数据。
在读/写数据段中,.data是已初始化的全局变量和静态变量;.bss是未初始化及所有初始化为0的全局变量和静态变量
内存保护

确保每一个进程都有单独的内存空间,内存分配前需要保证操作系统不受用户进程影响,同时保证用户进程不受其他用户进程影响

1.CPU中设置一对上下限寄存器,存放用户作业的上限和下限地址,确定该作业的地址范围

2.重定位寄存器(基址寄存器)和界地址寄存器(限长寄存器),作业地址范围为:重定位寄存器 到 重定位寄存器+界地址寄存器;加载重定位寄存器和界地址寄存器必须使用特权指令,不允许用户修改

内存共享

只有只读的区域才能共享

可重入的代码又称纯代码,允许多个进程同时访问但不允许修改;每个进程可以修改私有的数据区,不能修改共享代码

例:考虑一个可以同时容纳40个用户的多用户系统,他们同时执行一个文本编辑程序,若该程序有160KB代码区和
40KB数据区,则共需8000KB的内存空间来支持40个用户。如果160KB代码是可分享的纯代码,则不论是在分页系
统中还是在分段系统中,整个系统只需保留一份副本即可,此时所需的内存空间仅为40KB×40+160KB=1760KB。

对于分页系统,假设页面大小为4KB,则代码区占用40个页面、数据区占用10个页面。为实现代码共享,应在每个
进程的页表中都建立40个页表项,它们都指向共享代码区的物理页号。此外,每个进程还要为自己的数据区建立10个
页表项,指向私有数据区的物理页号。

对于分段系统,由于是以段为分配单位的,不管该段有多大,都只需为该段设置一个段表项(指向共享代码段始址,
以及段长160KB)。由此可见,段的共享非常简单易行。
内存分配与回收

单道程序-多道程序:单一连续分配-固定分配

适应大小不同的程序:固定分区-动态分区

更好地提高内存的利用率:连续分配-页式

满足用户在编程和使用方面的要求:段式

覆盖与交换

覆盖与交换技术是在多到程序环境下扩充内存的两种方法

1.覆盖:把用户空间分为一个固定区和若干覆盖区,将经常活动的部分放在固定区,其余部分按调用关系分段,将那些即将要访问的段放入覆盖区,其余段放在外存,需要调用时,再将其调入覆盖区,替换原有的段
打破了必须将一个进程全部信息装入主存后才能运行的限制;不在覆盖区的段会常驻内存,覆盖区的段能更新;覆盖技术对用户和程序员不透明
2.交换:把处于等待状态的程序移到外存,称为换出;把准备好的程序移入内存,称为换入
交换需要备份存储,通常是磁盘;为了有效使用CPU,需要使每个进程执行时间比交换时间长;换出进程必须完全处于空闲状态;交换空间通常作为磁盘的一整块,且独立于文件系统;交换通常会在系统忙时启动;

区别:交换技术主要在不同进程之间,覆盖则在同一个进程中;对于主存无法存放用户程序的矛盾,现代操作系统通过虚拟内存技术来解决的,覆盖技术已经成为历史;交换技术仍具有较强的生命力

3.1.2 连续分配管理方式

为一个用户程序分配一个连续的内存空间

内部碎片:分配给某些进程的内存区域中,有些部分没有用上
外部碎片:内存中某些空闲分区太小难以分配给程序
单一连续分配

在这里插入图片描述

系统被分为系统区和用户区:系统区通常位于低地址部分,用于存放操作系统相关数据;用户区存放用户进程相关数据;内存中只能有一道程序,占整个内存空间
优点:实现简单,无外部碎片;可采用覆盖技术;无须采取内存保护
缺点:只适用单用户、单任务的操作系统,有内部碎片,利用率低
固定连续分配

在这里插入图片描述

一种最简单的多道程序存储管理方式,将整个用户空间划分为若干个分区,每个分区只能装入一道作业
分区大小相等:缺乏灵活性
分区大小不等:
建立一张分区使用表
优点:实现简单,无外部碎片
缺点:程序太大时,可能所有分区都不满足,不得不采用覆盖技术,会产生内部碎片,内存利用率低

在这里插入图片描述

动态分区分配

又称可变分区分配,这种分配方式不会预先划分内存分区,而是进程装入内存时,根据进程大小动态建立分区,并使分区大小正好适合进程需要;大小和数目是可变的

紧凑技术:随着时间的推移,内存中会有越来越多的外部碎片,需要通过紧凑技术,不断对程序进行移动和整理,需要动态重定位寄存器的支持

动态分区分配没有内部碎片,但有外部碎片

动态分区分配会设置一张空闲分区链表,可以按始址排序
1.基于顺序搜索的分配算法
首次适用算法FirstFit:
每次都从低地址开始寻找,找到第一个满足大小的空闲分区;空闲分区以地址递增次序链接
算法简单,最好最快,回收分区后一般不需要对空闲分区列重新排序

最佳适应算法BestFit:
优先使用更小的分区,以保留更多大分区
空闲分区按容量递增形成空闲分区链,会产生大量小的、难以利用的外部碎片

最坏(最大)适应算法WorstFit:
优先使用更大的分区,以防止产生太小不可用的碎片
空闲分区以容量递减的次序链接,之后到达的大进程可能无足够的连续空间分配

邻近适应(循环首次适应)算法NextFit:
从上次查找的结束位置开始查找
空闲分区按地址递增的顺序排成一个循环链表;可能导致最后无大分区使用
2.基于索引搜索的分配算法:
当系统很大时,空闲分区链可能很长,大、中型系统中往往采用索引分配算法
根据其大小对空闲分区分类,对于每类(大小相同)的空闲分区,单独设立一个空闲分区链,并设置一张索引表来管理这些空闲分区链
当为进程分配空间时,在索引表中查找所需空间大小对应的表项,并从中得到头指针
索引分配算法有以下三种:

1.快速适应算法
空闲分区的分类根据常用的空间大小进行划分;第一,首先根据进程长度在索引表中找到能容纳他的最小空闲分区链表;第二,
从链表中取出第一块分配
优点是查找效率高、不产生内部碎片;缺点是回收分区时,需要有效合并分区,算法比较复杂,开销大

2.伙伴系统
规定所有分区的大小均为2的k次幂(k为正整数),为进程分配内存时,计算最小链表2^i分配,若已分配完,找2^(i+1)的链表将其等分
为两个分区,称为一对伙伴,其中一个分配,另一个加入2^i的空闲链表;若还不存在,则继续查找,直到找到为止;回收时,可能
也需要对伙伴分区进行合并

3.哈希算法
根据空闲分区链表的分布规律,建立哈希函数,构建一张以空闲分区大小为关键字的哈希表,每个表项记录对应头指针;分配时,
根据所需分区的大小,通过哈希函数计算得到哈希表中的位置,从中得到相应的空闲分区链表

以上都是连续分配,而非连续分配就是分页和分段管理

3.1.3 基本分页存储管理

连续分配中,固定分区会产生内部碎片;动态分区会产生外部碎片

分页思想:把主存空间划分为大小相等且固定的块,作为主存的基本单位。每个进程以块为单位进行划分,在运行过程中去申请主存空间;不会产生外部碎片,只会在最后一块有内部碎片

1.概念
页或页面:进程中的块
页框或页帧:内存中的块
块或磁盘:外存
页框=页帧=内存块=物理块=物理页面
为了方便地址转换,页面的大小应是2的整数幂

地址结构:页号+页内偏移量

页表:OS为每个进程建立一张页表,通常在PCB中,记录进程页面和实际内存块之间的映射关系
页号(对应逻辑地址,页表项在内存中连续存放,因此页号是可以隐藏的)+块号(对应物理内存)

地址转换:页号=逻辑地址/页面长度,页内偏移量=逻辑地址%页面长度
2.地址转换机构

在这里插入图片描述

通常会在系统中设置一个页表寄存器PTR,存放页表在内存中的起始地址F和页表长度M

进程未执行时,页表的始址和页表长度存放在PCB中,进程调度时再把他们放到页表寄存器

页号对应的页表项地址=页表起始地址+页号*页表项长度

分页管理系统中分页完全是由系统实现的

页表中页号可以隐含,不占内存空间

3.具有快表的地址变换机构

快表:相联存储器TLB,是一种访问速度比内存快很多的高速缓存器,用来存放最近访问页表项的副本,可以加速地址转换的速度;可以理解为一种特殊的cache

慢表:内存中的页表

在这里插入图片描述

地址转换时,先比较快表,若快表找不到在去内存比较慢表;找到页表项后,应同时将其存入快表,若快表已满,按照一定算法对旧的页表项进行替换(局部性原理)

4.两级页表

页目录表+页表

属于分页存储管理范畴,用于解决页表项占据连续页框的问题

单级页表的问题:1.页表项需要连续存放,当页表很大时,需要占用多个连续的页框;此时可以建立两级页表,一级页表为页目录表,二级页表离散存储;2.没必要让整个页表常驻内存,系统在一段时间内可能只需要访问几个特定页面;此时可以在需要访问时再把页面调入内存,在页表项中增加一个标志位,表示是否调入内存

需要多一次访存

3.1.4 基本分段存储管理

分页管理是从计算机的角度考虑设计的,目的是提高内存利用率,提升计算机性能;分页由硬件实现,对用户完全透明

分段管理是考虑用户和程序员,以满足方便编程、信息保护和共享、动态增长及动态链接等多方面的需要

地址结构是二维的

1.分段

按用户进程中的自然段划分逻辑空间;段内要求连续,段间不要求连续

在这里插入图片描述

逻辑地址=段号+段内偏移量;段号和段内偏移量由用户提供(编译程序完成)

2.段表

段表项=段号(隐藏)+段长+基址

3.地址变换机构

在这里插入图片描述

4.分页和分段的对比

分页:内存利用率高,但不方便按照逻辑模块实现信息的共享和保护

分段:方便按照逻辑模块实现信息的共享和保护,但如果段过长,会占用连续内存空间,会产生外部碎片

5.段的共享和保护

共享:分段系统中,共享是两个作业段表中的段表项指向同一个物理副本;不能修改的代码称为纯代码或可重入代码

保护:1.存取控制保护,指在段表项中设置存取控制字段;2.地址越界保护,检查逻辑地址是否超出进程的地址空间

3.1.5 段页式存储管理

将作业的地址空间首先分为若干逻辑段,每个段有自己的段号,然后将每个段分为若干大小固定的页

在这里插入图片描述

逻辑地址=段号+页号+页内偏移量

在一个进程中,段表只有一个,页表可能有多个

地址结构是二维的

地址转换:通过段表找到页表始址,然后通过页表找到页号,最后形成物理地址;需要三次访存

在这里插入图片描述

3.2 虚拟内存管理

虚拟内存基本概念、请求页式管理、页框分配、页置换算法

内存映射文件、虚拟存储器性能的影响因素及改进方式

3.2.1 基本概念

1.传统存储管理方式的特征
1.一次性:作业必须一次装入内存
当作业很大而不能全部装入内存时,无法运行
当大量作业要求运行时,只有一部分能装入内存,并发度下降
2.驻留性:作业装入内存后会长存内存直到运行结束,中间会有阻塞状态造成内存资源浪费
2.局部性原理
快表、页高速缓存和虚拟内存技术都是高速缓存技术,都依赖局部性原理
1.时间局部性:执行过的指令可能不久后会再一次执行;被访问过的数据可能不久后会再次访问;原因是有大量循环
2.空间局部性:访问的某个单元的邻近单元在不久后可能也会被访问;指令和数据通常顺序存储
3.虚拟存储器的定义和特征
虚拟存储器:
1.请求调页:程序装入时只要将当前需要的少数页面调入内存即可,在执行过程中,当所访问的信息不在内存时,由操作系统将需要的信息页面调入内存,称为请求调页
2.页面置换:当内存空间不够时,将内存中暂时用不到的页面调出外存,重新调入需要的信息

虚拟存储器特征:
1.多次性:多次调入调出,最重要的特征
2.对换性:无需常驻内存
3.虚拟性:逻辑上扩充内存的容量,实现最重要的目标
4.虚拟内存技术的实现
实现方式:
1.请求分页
2.请求分段
3.请求段页式

需要:
一定容量的内存和外存;页表机制;中断机构;地址变换机构

3.2.2 请求分页管理方式

请求分页管理 = 基本分页系统+请求调页+页面置换

1.页表机制

在这里插入图片描述

状态位P:标记该页是否已调入内存

访问字段A:记录该页一段时间内被访问的次数,供页面置换参考

修改位M:是否修改过,换出时是否需要写回外存

外存地址:通常是物理块号,供调入时参考

2.缺页中断机构

在请求分页系统中,当访问的页面不在内存时,产生一个缺页中断,请求操作系统的缺页中断程序处理;此时缺页的进程阻塞,调入页面完成后再将进程唤醒放入就绪队列。

若内存中有空闲页框,则直接从外存调入页框并修改页表项;若没有空闲页框,由页面置换算法选择一个页面淘汰,判断换出的页面是否要写回外存。

缺页中断:
在指令执行期间而非一条指令执行完后产生和处理中断,属于内部异常
一条指令执行期间可能多次缺页中断
3.地址变换机构

在这里插入图片描述

1.先检索快表,命中则取出物理块号,修改访问位,写指令还要把修改位置为1
2.快表未命中,查页表,找到时取出物理块号,并将该表项写入快表,若快表已满,需要替换
3.页表未找到,进行缺页中断,更新页表和快表,并获得物理块号
4.把得到的物理块号和页内地址拼接成物理地址

3.2.3 页框分配

1.驻留集大小

驻留集:给一个进程分配的页框的集合就是进程的驻留集

1.驻留集越小,内存中的进程就越多,可以提高多道程序的并发度;但分配给每个进程的页框太少,导致缺页率高
2.驻留集越大,当分配给进程的页框超过某个数目时,再为进程增加页框对缺页率的改善不大,反而浪费内存空间
2.内存分配策略
内存分配有固定分配和可变分配两种,页面置换时有全局置换和局部置换两种
1.固定分配局部置换:
为每个进程分配数目固定的物理块;局部置换是指发生缺页时,只能从分配给本进程的页面中选择一页换出
难以确定每个进程分配的物理块数,太少会频繁缺页中断,太多也降低利用率
2.可变分区全局置换:
先为每个进程分配一定数目的物理块,在运行期间可以适当增加或减少;全局置换是指发生中断时,可调入随意一个物理块
可以动态增加进程的物理块,但盲目增加会降低并发能力
3.可变分区全局置换:
为进程分配一定数目的物理块,缺页时只能在本进程分配的页面中调入调出;当频繁缺页中断时,系统再为进程分配若干物理
块,直到缺页率合适;反之,若缺页率特别低,可适当减少分配的物理块,但不能引起缺页率的明显增加
最理想,但实现最复杂
3.物理块调入算法
固定分配时:
1.平均分配算法
2.按比例分配算法:按进程的大小比例分配
3.优先权分配算法
通常是将所有可分配的物理块分成两部分,一部分按比例分配给各个进程;一部分根据优先权分配
4.调入页面时机
1.预调页策略:一次调入若干相邻页面回比一次调入一页更高效;主要用于首次调入,由程序员指出先调入哪些页
2.请求调页:缺页时调入
5.从何处调入页面

请求分页系统的外存分为:文件区和对换区(交换区)

对换区采用连续分配方式,速度较快,而文件区采用离散分配方式

1.系统有足够的对换区空间时:可全部从对换区调入所需页面;程序运行前需要将与该进程有关的文件从文件区复制到对换区
2.系统缺少足够的对换区空间:不会被修改的文件直接从文件区调入,这些页面不必换出,需要修改的部分,换出时将他们换
到对换区,以后需要再从对换区调入(因为读比写速度快)
3.unix方式:与进程有关的文件都放在文件区,从未运行过的页面都从文件区调入,曾经调入然后换出的页面在对换区,因此
下次调入从对换区调入;进程请求的共享页面若被其他进程调入内存,则不需要再从对换区调入
6.如何调入页面

3.2.4 页面置换算法

1.OPT最佳置换算法

选择淘汰以后永不使用的页面,或者最长时间不再被访问的页面;该算法无法实现

2.FIFO先进先出置换算法

使用队列实现

Belady现象:分配的物理块增多,缺页次数不减反增的现象

3.LRU最近最久未使用置换算法

选择最近最长时间未被使用的页面淘汰;每个页面设置一个访问字段,用来记录上次访问已过去的时长,淘汰值最大的页面

需要寄存器和硬件的支持,是堆栈类算法

4.CLOCK时钟置换算法

性能接近OPT算法,但实现起来开销大

1.简单时钟置换:
每个页面设置一个访问位A,首次被装入,或者被访问时,访问为置为1
所有页面连成一个循环队列,一个替换指针指向一个页面,当页面被替换时,指针指向下一页面
替换时只看访问位,若为1,把他修改为0,暂不换出,继续查看下一位;若为0,直接换出

2.改进型时钟算法:
页面换出时,被修改过的页面需要写回磁盘,开销较大,因此优先考虑换出未修改过的页面
设置访问位A和修改位M
淘汰次序:A=0,M=0,未被访问未被修改;A=0,M=1,未被访问已被修改;A=1,M=0,已被访问未被修改;A=1,M=1,已被访问已被修改
算法执行过程:
1.循环扫描,找A=0,M=0,这一轮不修改访问位A
2.找A=0,M=1,同时扫描过的页面访问位都改为0
3.再重复以上两步

3.2.5 抖动和工作集

1.抖动

刚刚换入内存的页面马上被换出,这种频繁的页面调度行为称为抖动或颠簸

发生的原因是分配的物理块太少

2.工作集

驻留集是为进程分配物理块的数量

工作集是一个时间内系统会用到的页面集合,可以重复

驻留集不能小于工作集,否则会发生抖动

3.2.6 内存映射文件

内存映射文件是操作系统向应用程序提供的一个系统调用,与虚拟内存有些相似,在磁盘文件和进程的虚拟地址空间之间建立映射关系。

将一个文件映射到虚拟地址空间,用访问内存的方式读写文件。将文件当成内存中一个大字符数组来访问而不通过文件IO方式来访问;文件也不会一次性读入内存。

进程可通过共享内存来通信,共享内存是通过映射相同文件到通信进程的虚拟地址空间来实现的;各进程虚拟地址空间相互独立,但映射到的物理内存相同

优点:1.程序员编程更简单,已建立映射的文件,只需按访问内存的方式进行读写;2.方便多个进程共享同一个磁盘文件

3.2.7 虚拟存储器性能影响因素

缺页率、分配给进程的物理块数、页面置换算法、写回磁盘的频率

3.2.8 地址翻译

  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值