计算机操作系统
- 进程的描述与控制
- 程序执行
- 进程
- 进程的定义与特征
- 相关概念
- 定义
- 特征
- 进程与程序的区别
- 进程的基本状态和转换
- PCB
- PCB中的信息
- 作用
- PCB的组织方式
- 线程
- 进程与线程的比较
- 处理机调度与死锁
- 处理机调度
- 处理机调度的层次
- 调度算法
- 处理机调度算法的目标
- 处理机调度算法的共同目标
- 批处理系统中处理机调度算法的目标
- 分时系统中处理机调度算法的目标
- 实时系统中处理机调度算法的目标
- 调度算法
- 先来先服务FCFS
- 短作业优先调度算法SJF
- 优先级调度算法
- 高响应比优先调度算法HRRN
- 轮转调度算法RR
- 多级队列调度算法
- 多级反馈队列调度算法
- 基于公平原则的调度算法
- 死锁
- 资源问题
- 死锁
- 进程同步
- 制约关系
- 相关概念
- 解决临界区问题的同步机制的4条准则
- 硬件同步机制
- 信号量机制
- 信号量的应用
- 管程机制
- PV操作题分析步骤
- 经典进程同步问题
- 生产者-消费者问题
- 多生产者-多消费者问题
- 哲学家进餐问题
- 读者-写者问题
- 存储器管理
- 程序的装入
- 程序的链接
- 对换与覆盖
- 连续分配存储管理方式
- 单一连续分配
- 固定分区分配
- 动态分区分配
- 动态分区分配算法
- 首次适应算法FF
- 循环首次适应算法NF
- 最佳适应算法BF
- 最坏适应算法WF
- 分区的回收
- 动态重定位分区分配
- 紧凑
- 动态重定位
- 分页存储管理方式
- 分段存储管理方式
- 段页式存储管理方式
- 虚拟存储器
- 虚拟存储器
- 请求页表机制
- 内存分配策略
- 页面置换算法
- 最佳页面置换算法(无法实现)
- 先进先出算法
- 最近最久未使用页面置换算法LRU
- 最少使用页面置换算法LFU
- Clock页面置换算法
- 抖动(Thrashing)
- 工作集
- 输入/输出系统
- I/O系统的基本功能
- I/O软件的层次结构
- I/O设备
- 设备与控制器之间的接口
- 设备控制器
进程的描述与控制
程序执行
程序顺序执行
程序需要按先后次序被顺序运行,仅当前一程序段运行完成后,才会运行后一程序段
特征:顺序性、封闭性、可再现性
程序并发执行
只有不存在前驱关系的程序才有可能并发执行,否则无法并发执行
特征:间断性、失去封闭性、不可再现性
进程
:使多个程序能并发执行,以提高资源利用率和系统吞吐量
进程的定义与特征
相关概念
- 进程控制块PCB:PCB是进程存在的唯一标志
- 进程实体:由程序段、相关的数据段和PCB三部分组成
定义
进程是程序的执行过程(是程序的一次执行),是系统进行资源分配和调度的一个独立单位。
特征
-
动态性(最基本的特征)
-
并发性
-
独立性:进程是一个能够独立运行、独立获得资源、独立接受调度的基本单位(①进程是一个可拥有资源的独立单位②进程又是一个可独立调度和分派的基本单位)
-
异步性
进程与程序的区别
进程是程序的执行过程,是动态的;而程序是一组有序指令的集合,是静态的
进程能够与其他进程并发执行,而程序(未建立PCB)不能参与并发执行
进程的基本状态和转换
- 就绪态(ready):CPU❌ 其他资源✅
- 执行态(running):CPU✅ 其他资源✅
- 阻塞态(block):CPU❌ 其他资源❌
- 创建态:由进程申请一个空白PCB,并向PCB中填写用于控制和管理进程的信息;然后为该进程分配运行时所必需的资源;初始化PCB;最后将该进程的状态转换为就绪状态并将其插入就绪队列之中
- 终止态:等待OS进行善后处理;然后将进程PCB清零并将PCB空间返还OS
PCB
PCB中的信息
-
进程标识符PID:用于唯一标志一个进程
-
处理机状态
处理机处于执行状态时,正在处理的许多信息都放在寄存器中。当进程被切换时,处理机状态信息都必须保存在相应的PCB中,以便在该进程被重新调度时,能再从断点处继续执行 -
进程调度信息
①进程状态。作为进程调度和对换时的依据
②进程优先级
③进程调度所需要的其他信息,与调度算法有关
④事件。指进程由执行状态转换为阻塞状态所等待发生的事件,即阻塞原因 -
进程控制信息
①程序和数据的地址
②进程同步和通信机制
③资源清单,列出进程在运行期间所需的全部资源(除CPU外)
④链接指针,给出本进程所在队列中的下一个进程的PCB的始址
作用
(1)作为独立运行基本单位的标志:PCB是进程存在于系统中的唯一标志
(2)实现间断性运行方式:系统将CPU现场信息保存在被中断进程的PCB中,供该进程再次被调度运行而须回复CPU现场信息时使用
(3)提供进程管理所需要的信息
(4)提供进程调度所需要的信息
(5)实现于其他进程的同步与通信
PCB的组织方式
- 线性方式
- 链接方式
- 索引方式
线程
:减少程序在并发执行时所付出的时空开销,以使OS具有更好的并发性
线程作为调度和分派的基本单位
进程与线程的比较
-
线程是调度和分派的基本单位,因而线程是能独立运行的基本单位。当线程切换时,仅需保存和设置少量寄存器的内容,切换代价远小于进程。
在同一进程中,线程的切换不会引起进程的切换,但从一个进程中的线程切换到另一个进程中的线程时,必然会引起进程的切换 -
并发性
进程之间可以并发执行
一个进程中的多个线程之间也可以并发执行
不同进程的线程也可以并发执行
-
拥有资源
进程是拥有资源的基本单位;而线程几乎不拥有资源
线程可以共享它们共属的进程所拥有的资源
-
独立性
同一进程中的不同线程之间的独立性要比不同进程之间的独立性低很多。
原因:每个进程都有独立的地址空间和其他资源,除共享全局变量外,不允许自身以外的进程访问自己地址空间中的地址;而同一进程中的不同线程可以共享进程的内存地址空间和资源。
-
系统开销
线程的切换代价远低于进程
-
支持多处理机系统
可以将一个进程中的多个线程分配到多个处理机上
处理机调度与死锁
处理机调度
处理机调度的层次
-
高级调度
调度对象:作业
位置:外存→内存
状态:无→创建态→就绪态
功能:根据某种算法决定将外存上处于后备队列中的那几个作业调入内存,为它们创建进程、分配必要的资源,并将它们放入就绪队列。
用于:多道批处理系统
-
中级调度
位置:外存→内存
状态:挂起态→就绪态
功能:决定将外存上已具备运行条件的就绪进程再重新调入内存,并修改它们的状态为就绪态,并将它们放入就绪队列
实际上是存储器管理中的对换功能 -
低级调度
调度对象:进程
位置:内存→CPU
状态:就绪态→运行态
功能:根据某种算法决定就绪队列中的哪个进程应获得处理机,并由分派程序将处理机分配给被选中的进程。
最基本的一种调度,多道批处理系统、分时和实时系统都必须配置这种调度。
调度算法
处理机调度算法的目标
处理机调度算法的共同目标
-
资源利用率
-
公平性
-
平衡性
-
策略强制执行
批处理系统中处理机调度算法的目标
- 平均周转时间短
- 系统吞吐量高
- 处理机利用率高
分时系统中处理机调度算法的目标
- 保证响应时间快
- 保证均衡性
实时系统中处理机调度算法的目标
- 保证满足截止时间的要求
- 保证可预测性
调度算法
先来先服务FCFS
短作业优先调度算法SJF
缺点:
①必须预先知道作业的运行时间。
②对长作业非常不利,可能会使长作业等待时间过长,出现饥饿现象。
③无法实现人机交互。
④没有考虑作业的紧迫程度
优先级调度算法
类型:非抢占式、抢占式
优先级类型:静态优先级、动态优先级(先赋予一个优先级,然后随进程的推进或等待时间的增加而改变)
高响应比优先调度算法HRRN
特点:
①如果作业的等待时间相同,则要求服务时间越短,优先级越高,此时类似于SJF调度算法,有利于短作业。
②当作业的要求服务时间相同时,其优先级又取决于等待时间,此时类似于FCFS调度算法。
③对于长作业的优先级,其可随等待时间的增加而提高,当作业的等待时间足够长时,也可以获得处理机。
轮转调度算法RR
系统将所有就绪进程按FCFS策略排成一个就绪队列。把处理机分配给队首的进程,并令其执行一个时间片
进程切换时机:
①一个时间片尚未用完而正在运行的进程已经完成;
②时间片用完,如果进程尚未运行完毕,调度程序就把它送往就绪队列的末尾。
时间片大小的确定:若选择很小的时间片,则将有利于短作业,但意味着系统会频繁地执行进程调度和进程上下文的切换,无疑会增加系统的开销;若选择太大的时间片,则会退化为FCFS调度算法。一个较为可取的时间片大小是略大于一次典型交互所需要的时间。
多级队列调度算法
将进程就绪队列拆分成若干个,将不同类型或性质的进程固定分配在不同的就绪队列,不同的就绪队列采用不同的调度算法。
多级反馈队列调度算法
- 设置多个就绪队列
设置多个就绪队列,并为其设置不同的优先级。为不同队列的进程设置不同的执行时间片大小,优先级越高的队列时间片越小。 - 每个队列都采用FCFS调度算法
当新进程进入内存,首先将其放在第一个队列的末尾,按FCFS策略等待调度。当轮到该进程执行时,如果它能在该时间片内完成,则可撤离系统;否则将其转入第二个队列末尾等待调度,以此类推。当进程最后被降到第n队列后,在第n队列中采取RR方式运行 - 按队列优先级调度
仅当第1~i-1队列均空时,才会调度第i队列中的进程运行
基于公平原则的调度算法
死锁
资源问题
- 可重用资源和可消耗资源
可重用资源:可供用户重复使用多次的资源
性质:
①每个可重用资源中的单元只能分配给一个进程使用,而不允许多个进程共享。
②进程若要使用可重用资源,要按以下步骤:请求资源(若请求失败,则进程将会被阻塞或循环等待)→使用资源→释放资源。
③每类可重用资源中的单元数目是相对固定的,进程在运行期间既不能创建资源也不能删除资源
可消耗资源(临时资源):在进程运行期间由进程动态创建和消耗的 - 可抢占资源和不可抢占资源
可抢占资源
不可抢占资源
死锁
起因:
- 竞争不可抢占资源引起死锁
- 竞争可消耗资源引起死锁
- 进程推进顺序不当引起死锁
定义:如果一组进程中的每个进程都在等待仅由该组进程中的其他进程才能引发的事件发生,那么该组进程是死锁的。
必要条件:
产生死必须同时具备以下4个必要条件:
- 互斥条件
- 请求和保持条件
进程已经占有至少一个资源,但又提出新的资源请求,而该被请求的资源已被其他进程占有,此时请求进程被阻塞,同时对其自己已占有的资源保持不放。 - 不可抢占条件
- 循环等待条件
发生死锁时必然存在一个“进程-资源”循环链
处理方法
- 死锁预防
破坏产生死锁的4个必要条件中的一个或几个:
①破坏“请求和保持”条件
第一种协议:所有进程在开始运行之前,必须一次性地申请其在整个运行过程中所需要的全部资源,在运行期间不再申请资源。
第二种协议:是对第一种协议的改进。允许一个进程只获得运行初期所需的资源后,便开始运行。在运行过程中逐步释放已分配给自己的且已用毕的全部资源,然后再申请新的资源。
②破坏“不可抢占”条件
当一个已经保持了某些不可抢占资源的进程提出新的资源请求而不能得到满足时,必须释放已经保持的所有资源,待以后需要时再重新申请。
③破坏“循环等待”条件
对系统的所有资源进行线性排序并赋予不同的序号。
规定每个进程必须按序号递增的顺序请求资源。若进程已请求到一些序号较高的资源后来又想请求序号较低的资源,则必须先释放所有具有相同和更高序号的资源。 - 避免死锁
相关概念- 安全状态:系统能按某种进程推进顺序(安全序列),为每个进程分配资源,使每个进程都可顺利完成的一种系统状态。
- 不安全状态:系统无法找到一个安全序列,使进程顺利完成
- 检测死锁
死锁定理 - 解除死锁
①抢占资源,从一个或多个进程中抢占足够数量的资源,然后将它们分配给死锁进程
②终止死锁进程,终止系统中一个或多个死锁进程,直至打破循环等待
终止死锁的方法:
-终止所有死锁进程
-逐个终止死锁进程
进程同步
制约关系
- 互斥关系(间接相互制约关系)
- 同步关系(直接相互制约关系)
相关概念
临界资源:进程在使用的时候需要采用互斥的方式的资源
进入区:检查是否可进入临界区,若可进入,需要“上锁”
临界区:访问临界资源的那段代码
退出区:“解锁”
解决临界区问题的同步机制的4条准则
- 空闲让进
- 忙则等待
- 有限等待
- 让权等待:当进程不能进入自己的临近区时,应立即释放处理机,以免进程陷入“忙等”状态
硬件同步机制
- 关中断
在进入锁测试之前,关闭中断,直到完成锁测试并上锁之后,才能打开中断
...
关中断;
临界区;
开中断;
...
缺点:
①滥用关中断权力可能导致严重后果;
②关中断时间过长会影响系统效率,进而限制CPU交叉执行程序的能力;
③关中断方法不适用于多CPU系统
- Test-and-Set
- swap指令
信号量机制
- 整型信号量(信号)
wait(S){
while(S <= 0);
S--;
}
signal(S){
S++;
}
- 记录型信号量(信号量)
typedef struct {
int value;
struct process_control_block *list;
}semaphore;
wait(semaphore *S){
S->value--;
if(S->value<0)
block(S->list);
}
signal(semaphore *S){
S->value++;
if(S->value<=0)
wakeup(S->list);
}
- AND型信号量
将进程在整个运行过程中需要的所有资源,一次性全部分配给进程,待进程使用完后再一起释放。 - 信号量集
信号量的应用
wait—P、signal—V
- 实现进程互斥
设置互斥型信号量mutex,并设初值为1,取值范围为(-1,0,1)
semaphore mutex=1;
PA(){
while(1){
wait(mutex);
临界区;
signal(mutex);
剩余区;
}
}
PB(){
while(1){
wait(mutex);
临界区;
signal(mutex);
剩余区;
}
}
wait(mutex)和signal(mutex)必须成对出现
2. 实现进程同步
设置同步型信号量S,并设初值为0,取值范围为(-1,0,1)
semaphore S=0;
P1(){
while(1){
C1;
signal(S);
...
}
}
P2(){
while(1){
wait(S);
C2;
...
}
}
- 实现前驱后继关系
semaphore a1, a2, b, c, d = 0;
S1(){
...;
V(a1);V(a2);
}
S2(){
P(a1);
...;
V(b);
}
S3(){
P(a2);
...;
V(c);
}
S4(){
P(b);P(c);
...;
V(d);
}
S5(){
P(d);
...;
}
管程机制
管程是一种特殊的软件模块,有这些部分组成:(有点类似于面向对象的类)
- 局部于管程的共享数据结构说明;
- 对该数据结构进行操作的一组过程;(类似函数)
- 对局部于管程的共享数据设置初始值的语句;
- 管程有一个名字。
管程的基本特征:
- 局部于管程的数据只能被局部于管程的过程所访问;
- 一个进程只有通过调用管程内的过程才能进入管程访问共享数据;
- 每次仅允许一个进程在管程内执行某个内部过程。
PV操作题分析步骤
- 分析进程的同步(一前一后)、互斥关系
- 根据各进程的操作流程确定PV操作的大致顺序
①互斥:在临界区前后分别PV
②同步:前V后P - 设置信号量并设置初值
①互斥信号量一般为1
②同步信号量看对应资源的初始值是多少
经典进程同步问题
生产者-消费者问题
系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用。
问题分析:
生产者、消费者共享一个初始为空、大小为n的缓冲区。
只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待。
只有缓冲区不空时,消费者才能从中取出产品,否则必须等待。
缓冲区是临界资源,各进程必须互斥地访问。互斥关系
semaphore mutex = 1; //互斥信号量,实现对缓冲区的互斥访问
semaphore empty = n; //同步信号量,表示空闲缓冲区的数量
semaphore full = 0; //同步信号量,表示产品的数量,也即非空缓冲区的数量
producer (){
while(1){
生产一个产品;
P(empty); //检查是否有空闲缓冲区
P(mutex); //互斥地使用临界区资源
把产品放入缓冲区;
V(mutex);
V(full);(增加一个产品)
}
}
consumer (){
while(1){
P(full); //消耗一个产品(非空缓冲区)
P(mutex);
从缓冲区取出一个产品;
V(mutex);
V(empty); //增加一个空闲缓冲区
使用产品;
}
}
多生产者-多消费者问题
桌子上有一只盘子,每次只能向其中放入一个水果。爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,儿子专等着吃盘子中的橘子,女儿专等着吃盘子中的苹果。只有盘子空时,爸爸或妈妈才可向盘子中放一个水果。仅当盘子中有自己需要的水果时,儿子或女儿可以从盘子中取出水果。
问题分析:
互斥关系(mutex = 1):
对缓冲区(盘子)的访问要互斥地进行
同步关系(一前一后):
1. 父亲将苹果放入盘子后,女儿才能取苹果
2. 母亲将橘子放入盘子后,儿子才能取橘子
3. 只有盘子为空时,父亲或母亲才能放入水果
semaphore mutex = 1; //实现互斥访问盘子(缓冲区)
semaphore apple = 0; //盘子中有几个苹果
semaphore orange = 0; //盘子中有几个橘子
semaphore plate = 1; //盘子中还可以放多少个水果
dad (){
while(1){
准备一个苹果;
P(plate);
P(mutex);
把苹果放入盘子;
V(mutex);
V(apple);
}
}
mom (){
while(1){
准备一个橘子;
P(plate);
P(mutex);
把橘子放入盘子;
V(mutex);
V(orange);
}
}
daughter (){
while(1){
P(apple);
P(mutex);
从盘中取出苹果;
V(mutex);
V(plate);
吃掉苹果;
}
}
son (){
while(1){
P(orange);
P(mutex);
从盘中取出橘子;
V(mutex);
V(plate);
吃掉橘子;
}
}
哲学家进餐问题
一张圆桌上坐着5名哲学家,每两个哲学家之间的桌上摆一根筷子,桌子的中间是一碗米饭。哲学家们倾注毕生的精力用于思考和进餐,哲学家在思考时,并不影响他人。只有当哲学家饥饿时,才试图拿起左、右两根筷子(一根一根地拿起)。如果筷子已在他人手上,则需等待。饥饿的哲学家只有同时拿起两根筷子才可以开始进餐,当进餐完毕后,放下筷子继续思考。
问题分析:
①关系分析。系统中有5个哲学家进程,5位哲学家与左右邻居对其中间筷子的访问是互斥关系。
② 整理思路。每个哲学家进程需要同时持有两个临界资源才能开始吃饭。
③ 信号量设置。定义互斥信号量数组chopstick[5]={1,1,1,1,1} 用于实现对5个筷子的互斥访问。并对哲学家按0~4编号,哲学家 i 左边的筷子编号为 i,右边的筷子编号为 (i+1)%5。
semaphore chopstick[5]={1,1,1,1,1};
semaphore mutex = 1; //互斥地取筷子
Pi (){ //i号哲学家的进程
while(1){
P(mutex);
P(chopstick[i]); //拿左
P(chopstick[(i+1)%5]); //拿右
V(mutex);
吃饭…
V(chopstick[i]); //放左
V(chopstick[(i+1)%5]); //放右
思考…
}
}
读者-写者问题
有读者和写者两组并发进程,共享一个文件,当两个或两个以上的读进程同时访问共享数据时不会产生副作用,但若某个写进程和其他进程(读进程或写进程)同时访问共享数据时则可能导致数据不一致的错误。因此要求:①允许多个读者可以同时对文件执行读操作;②只允许一个写者往文件中写信息;③任一写者在完成写操作之前不允许其他读者或写者工作;④写者执行写操作前,应让已有的读者和写者全部退出。
问题分析:
两类进程:写进程、读进程
互斥关系:写进程—写进程、写进程—读进程。读进程与读进程不存在互斥问题。
semaphore rw=1; //用于实现对共享文件的互斥访问
int count = 0; //记录当前有几个读进程在访问文件
semaphore mutex = 1; //用于保证对count变量的互斥访问
semaphore w = 1; //用于实现“写优先”,防止写者饿死
writer (){
while(1){
P(w);
P(rw);
写文件…
V(rw);
V(w);
}
}
reader (){
while(1){
P(w);
P(mutex);
if(count==0)
P(rw);
count++;
V(mutex);
V(w);
读文件…
P(mutex);
count--;
if(count==0)
V(rw);
V(mutex);
}
}
存储器管理
存储器的层次结构
通用计算机存储层次至少应具有3层:CPU寄存器、主存储器、辅助存储器
细分可分为:寄存器、高速缓存、主存储器、磁盘缓存、固定磁盘、可移动存储介质
逻辑地址和物理地址
逻辑地址(相对地址):CPU生成的地址
物理地址(绝对地址):装入内存地址寄存器的地址
内存保护
通过基址寄存器、界限寄存器进行保护
基地址:最小合法物理地址
界限地址:合法范围的大小
判断:基地址≤物理地址<(基地址+界限地址)
程序的装入
1. 绝对装入方式
2. 可重定位装入方式
3. 动态运行时装入
程序的链接
1. 静态链接
2. 装入时动态链接
3. 运行时动态链接
对换与覆盖
对换(不同进程或作业间)
:把处于等待状态(或在CPU调度原则下被剥夺运行权利)的程序从内存移到辅存,把内存空间腾出来(换出);把准备好竞争CPU运行的程序从辅存移到内存(换入)
换出的进程的PCB仍留在内存
==>改善内存利用率
类型:
1. 整体对换 :以整个进程为单位
2. 页面(分段)对换 :以一个页面或分段为单位
对换区管理的主要目标
文件区管理的主要目标:提高文件存储空间的利用率,提高对文件的访问速度。
==>采用**离散分配**的存储管理方式
对换区管理的主要目标:提高进程换入和患处的速度,提高文件存储空间的利用率
==>采用**连续分配**存储管理方式
覆盖(一个程序或进程内)
:将用户空间分成一个固定区和若干覆盖区。将经常活跃的部分放在固定区,其余部分按调用关系分段。将即将要访问的段放入覆盖区,其余放在外存,有需要调用前,系统将其调入覆盖区,覆盖原有的段。
连续分配存储管理方式
单一连续分配
:在用户区内存仅装有一道用户程序
固定分区分配
:将用户空间划分成若干个固定大小的区域,并在每个分区中只装入一道作业
动态分区分配
数据结构:①空闲分区表;②空闲分区链
动态分区分配算法
首次适应算法FF
要求:
空闲分区链以地址递增的次序链接
从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区为止
特点:
保留了高址部分的大空闲分区,为以后到达的大作业分配大的内存空间创造了条件
低址部分不断被划分,进而留下许多难以利用的很小的空闲分区(碎片)
每次从链首开始查找,增加查找时的开销
循环首次适应算法NF
要求:
从上次找到的空闲分区的下一个空闲分区开始查找
特点:
使内存中的空闲分区分布更均匀,从而减少查找空闲分区的开销
大的空闲分区缺乏
最佳适应算法BF
要求:
所有空闲分区按容量从小到大的顺序,排成一个空闲分区链
把能满足要求的最小的空闲分区分配给作业
特点:
每次分配后割下来的剩余部分总是最小,留下许多难以利用的碎片
最坏适应算法WF
要求:
将所有分区按容量从大到小排成一个空闲分区链
挑选最大的空闲区进行分配
特点:
缺乏大的空闲分区
查找效率高
分区的回收
可能出现的四种情况:
1. 回收区与插入点的前一个空闲分区F1相邻,则将其与前一空闲分区合并,修改前一空闲分区F1的大小即可
2. 回收区与插入点的后一个空闲分区F1相邻,则将其与后一空闲分区合并,以回收区的起始地址作为新空闲区的起始地址
3. 回收区同时与插入点的前一个和后一个空闲分区相邻,则取消后一空闲分区的表项,将前一空闲分区的大小改为三者之和
4. 回收区与前后空闲区域均不相邻,则新增一个表项,以回收区低址为起始地址,并插入空闲分区链表中的适当位置
动态重定位分区分配
紧凑
把原来分散的多个小分区拼接成一个大分区
缺点:每紧凑一次,需要对移动了的程序或数据的地址进行修改,大大影响系统的效率
动态重定位
内存地址=相对地址+重定位寄存器中的地址
分页存储管理方式
基本概念:
①进程中的块——页/页面(Page)
②内存中的块——页框/页帧(Page Frame)
③外存——块/盘块(Block)
④页表:实现从页号到块号的地址映射
⑤地址结构
若给定一个逻辑地址空间的地址为A,页面大小为L,则页号P和页内地址d可按下式求得:
页表存放于内存中,CPU每次存取一个 数据时都要访问内存两次。第一次是访问内存中的页表,第二次是访问获得的物理地址中的数据
==>快表:采用小但专用且快速的硬件缓冲
未使用快表的内存有效访问时间
使用快表的内存有效访问时间EAT=a+(1-a)
分段存储管理方式
引入目的:为了满足用户(程序员)在编程和使用上多方面的要求
满足多方面的需求:
- 方便编程
用户将自己的作业按照逻辑关系划分为若干个段,每个段都是从0开始编址,并有自己的名字和长度。因此,希望访问的逻辑地址是由段名(段号)和段内偏移量(段内地址)决定的 - 信息共享
在实现对程序和数据的共享时,是以信息的逻辑单位为基础的。分页系统中的“页”只是存放信息的物理单位,并无完整的意义,不便于实现共享;然而段却是信息的逻辑单位。 - 信息保护
信息保护同样是对信息的逻辑单位进行保护 - 动态链接
- 动态增长
在实际应用中,往往有些段(特别是数据段),在使用过程中会不断地增长
在分段存储管理方式中,作业的地址空间被划分为若干个段,每个段定义了一组逻辑信息。
每个段都有自己的名字,通常用一个段号来代替段名,每个段都从0开始编址,并存储在一段连续的地址空间内
段的长度由相应的逻辑信息组的长度决定,因此各段长度不等。
段表:用于实现从逻辑段到物理内存区的映射
每个段在表中占有一个表项,记录了该段在内存中的起始地址(基址)和段的长度。
段页式存储管理方式
分段和分页原理的结合,即先将用户程序分成若干段,再把每个段分成若干个页,并为每个段赋予一个段名。
优点:
- 既有分段系统的便于实现、可共享、易于保护、可动态链接;
- 又能像分页系统,很好地解决内存的外部碎片问题。
虚拟存储器
前面的存储器管理方式都有两个共同特点:
- 一次性:作业必须一次性的全部装入内存后,方能开始运行
- 驻留性:作业被装入内存后,整个作业都一直驻留在内存中,其中任何部分都不会被换出,直到作业运行结束。
局部性原理:
-
时间局部性(循环操作):一条指令被执行了,则在不久的将来它可能再被执行
-
空间局部性(顺序执行):若某一存储单元被使用,则不久后与之相邻的单元可能被使用。
虚拟存储器
定义:具有请求调入功能和置换功能,能从逻辑上对内存容量加以扩充的一种寄存器系统
特征:
多次性:作业中的程序和数据允许被分成多次调入内存允许
对换性:作业运行时无须常驻内存
虚拟性:从逻辑上扩充了内存容量,使用户看到的内存容量远大于实际内存容量
请求页表机制
状态位P:指示该页是否在内存
访问字段A:记录该页在一段时间内被访问的次数
修改位M:也称脏位,标志该页是否被修改过
外存地址:指示该页在外存中的地址(物理块号)
请求分页中的内存分配
内存分配策略
固定分配局部置换
可变分配全局置换:只要缺页就给分配新物理块
可变分配局部置换:要根据发生缺页的频率来动态地增加或减少进程的物理块
页面置换算法
最佳页面置换算法(无法实现)
:淘汰未来最长时间不会被访问的页面
先进先出算法
最近最久未使用页面置换算法LRU
最少使用页面置换算法LFU
Clock页面置换算法
- 简单CLOCK算法
为每个页面设置一个访问位,再将内存中的页面都通过链接指针链接成一个循环队列。当某页被访问时,其访问位置为1。当需要淘汰一个页面时,只需检查页的访问位。如果是0,就选择该页换出;如果是1,则将它置为0,暂不换出,继续检查下一个页面,若第一轮扫描中所有页面都是1,则将这些页面的访问位依次置为0后,再进行第二轮扫描(第二轮扫描中一定会有访问位为0的页面) - 改进型CLOCK算法:
如果被淘汰的页面没有被修改过,就不需要执行I/O操作写回外存。只有被淘汰的页面被修改过时,才需要写回外存。
==>在其他条件都相同时,应优先淘汰没有修改过的页面,避免I/O操作。
为方便讨论,用(访问位,修改位)的形式表示各页面状态。
算法规则:
将所有可能被置换的页面排成一个循环队列
第一轮:从当前位置开始扫描到第一个(0, 0)的帧用于替换。本轮扫描不修改任何标志位
第二轮:若第一轮扫描失败,则重新扫描,查找第一个(0, 1)的帧用于替换。本轮将所有扫描过的帧访问位设为0
第三轮:若第二轮扫描失败,则重新扫描,查找第一个(0, 0)的帧用于替换。本轮扫描不修改任何标志位
第四轮:若第三轮扫描失败,则重新扫描,查找第一个(0, 1)的帧用于替换。
抖动(Thrashing)
:一个进程的页面经常换入换出(刚被换出的页面很快又被调入)
原因:同时在系统中运行的进程太多,因此分配给每一个进程的物理块太少,不能满足进程运行的基本要求,致使进程在运行时,频繁缺页,必须请求系统将所缺页面调入内存。
工作集
:指在某段时间间隔Δ里进程实际要访问页面的集合。
输入/输出系统
I/O系统的基本功能
-
能够隐藏物理设备的细节
-
能够保证OS与设备无关
-
提高处理机和I/O设备的利用率
-
能够对I/O设备进行控制
控制方式:
①轮询的可编程I/O方式
②中断的可编程I/O方式:打印机、键盘等低速设备
③直接存储器访问(DMA)方式:磁盘、光盘等高速设备
④I/O通道方式 -
能够确保对设备的正确共享
-
能够处理错误
I/O软件的层次结构
I/O设备
-
按使用特性分类:
存储设备:外存、辅存
I/O设备:输入设备、输出设备和交互式设备 -
按传输速率分类:
低速设备:键盘、鼠标
中速设备:行式打印机、激光打印机
高速设备:磁带机、磁盘机、光盘机 -
按信息交换单位分类:
块设备
字设备 -
按设备的共享属性分类:
独占设备
共享设备
设备与控制器之间的接口
数据信号线
控制信号线
状态信号线
设备控制器
主要功能:控制一个或多个I/O设备,以实现I/O设备和计算机之间的数据交换
基本功能:
- 接收和识别命令
- 数据交换
- 标识和报告设备的状态
- 地址识别
- 数据缓冲区
- 差错控制
设备控制器的组成: