提示:该文章仅面向期末考试的知识点复习,不涉及考研等。
操作系统是计算机用户与计算机硬件之间的接口
操作系统是计算机资源的管理者
进程并发执行是指在同一时间间隔内运行多个程序,在一个程序执行结束之前可以运行其他程序。
程序并发执行的特点
1)间断性:资源的有限性使得并发执行程序呈现执行过程中的间断性
2)失去封闭性:多个程序共享系统资源,系统的状态不再是只有正在执行的某一个程序可以看见或改变
3)不可再现性:不同的指令执行顺序交错,导致程序多次执行的结果出现不唯一的情况。
举例:失去封闭性,导致结果不可在现。
有两个并发执行的进程P1和P2,共享初值为1的变量x。P1对x加1,P2对x减1。加1和减1操作的指令序列分别如下所示。请写出出每种x的最后结果值对应的指令执行序列。
答案:x最后可能的结果为0,1,2
进程是程序在一个数据集合上的运行过程。由正文段、用户数据段和系统数据段共同组成的一个执行环境。正文段存放机器指令;用户数据段存放进程在执行过程中直接进行操作的所有数据;系统数据段存放程序的运行环境。
进程的特征
① 并发性
② 动态性:进程是进程尸体的执行过程,其动态性表现在进程创建、执行、状态转变和运行终止被撤销的动态变化过程。
③ 独立性:进程是独立运行和资源调度的基本单位
④ 异步性:进程以不同的、不可预知的速度推进
⑤ 结构特征
进程与程序的比较
区别:程序是静态的、永久的,进程是动态的、暂时的;程序和进程的存在实体不同。
联系:进程总是对应一个特定的程序,一个进程必然对应至少一段程序;一个程序可以对应多个进程。
进程控制块(PCB)是进程实体的一部分,是一种记录型数据结构,其记录了操作系统所需要的用于描述进程情况及控制进程运行所需的全部信息。PCB是在创建进程前创建的,每一个进程有唯一的进程控制块。
进程控制块中的信息
1)进程标识符信息:用于唯一表示一个进程。
2)处理机状态信息:处理机是被进程共享的资源。
3)进程调度信息
4)进程控制信息
进程控制块的作用
以Linux的进程控制块结构中的变量举例说明
(1)进程控制块中的time_slice字段用来记录进程在CPU上运行的时间片中还剩余的时钟节拍数。内核利用进程控制块的time_slice字段跟踪和控制进程在CPU上的执行时间,以防止进程超时使用CPU独占CPU资源。
(2)进程控制块中的prio字段用来存放进程的动态优先权,可以利用这个字段来比较进程的优先权,把资源分配给prio字段值最大的进程。
进程的组织
(1)链接方式:把具有相同状态(执行态、阻塞态、就绪态)的PCB用其中的链接字链接成一个队列。
(2)索引方式:根据所有进程的状态建立几张索引表。
不使用数组的原因:① 使用数组空间性能不好,会造成空间浪费或不够用。② 使用数组操作不灵活,时间性能不好。
就绪状态:进程一但获得CPU就可以投入运行的状态。
执行状态:进程获得CPU正在运行的状态。
阻塞状态:进程由于等待资源或某个事件的发生而暂停执行的状态。
进程队列
相同状态的进程放在同一个队列中。
就绪队列:可按照优先权分成不同的就绪队列。
阻塞队列:可根据阻塞原因的不同分成不同的阻塞队列。
进程创建的一般步骤
① 申请空白PCB
② 为新进程分配资源(由操作系统或者父进程完成)
③ 初始化进程控制块(进行一些赋值操作)
④ 将新进程插入就绪队列
进行进程阻塞是为了防止CPU效率低
引起进程阻塞的事件:请求系统服务如打印服务;启动某种操作如启动打印机;新数据尚未到达;无新工作可做。
进程阻塞的过程
① 暂停程序的进行,将进程的状态改为阻塞态;
② 将进程插入相应的阻塞队列(根据不同的阻塞原因);
③ 转进程调度程序,重新进行进程调度(选新进程到CPU运行)。
过程
① 将进程从阻塞队列中移出
② 将进程状态由阻塞改为就绪
③ 将进程插入就绪队列
进程终止过程
① 从进程PCB中读进程状态
② 若进程正在执行则终止进程的执行
③ 若进程有子孙进程则终止子孙进程(不一定)
④ 释放资源
⑤ 将终止进程的PCB“移”出
(1)什么是中断?
中断时改变处理器执行指令顺序的一种事件。当出现中断时,计算机停止现行程序的运行,转向对这些中断事件的处理,处理结束后再返回到现行程序的间断处。引入中断机制能有效地提高CPU的利用率,改善系统性能,支持系统的异步性。
(2)中断分为同步中断和异步中断。
同步中断:也叫内部中断或者异常,同步中断是当指令执行时由CPU控制单元产生的。只有一条指令终止执行后CPU才会发出中断,如除法出错、溢出、浮点出错等。
异步中断:也叫外部中断,是由其他硬件设备依照CPU时钟信号随机产生的。外部中断分为外部可屏蔽中断(由I/O设备产生的)和外部不可屏蔽中断(由紧急事件引起的,如硬件故障)。
(3)单重中断的执行过程
响应中断的前条件:对于可屏蔽中断,开中断是是相应中断的前提。
响应中断的时机:CPU在反复执行指令的过程中,每执行完一条指令,都会去检测是否有外部中断信号到来。如果检测到有中断信号,则转中断处理过程。
① 保存断点,把当前要执行的下一条指令的地址保存到内存中。
② 系统关闭中断,转中断处理程序,在中断处理程序中完成保存现场的工作,即把相关的硬件上下文信息保存到内存中。硬件上下文是中断返回恢复被中断程序的执行时,需要写回CPU寄存器的值。
③ 执行特定的中断服务子程序
④ 恢复现场,开中断,CPU返回断点处继续执行被中断的程序。
(4)如何找到中断服务子程序
中断向量:对不同中断源到来的信号进行编号,编号是一个无符号整数(0~255),称之为中断向量。
不可屏蔽中断和异常的向量是固定的,可屏蔽中断的向量可以通过对中断控制器的编程来改变。
中断向量表(IDT):每一个向量在表中有相应的中断或异常处理程序的入口地址信息(中断向量的值是连续的存放在IDT中的)。
寻找中断服务子程序的过程:不同的中断源对应不同的中断向量 -> 根据中断向量查找中断向量表 -> 从中断向量表中的表项中读取中断处理子程序的入口地址相关信息。
IDT的每一项都对应一个中断或异常向量,每个表项由8个字节组成。IDT表的起始地址存放在idtr CPU寄存器中。idtr CPU寄存器可以是IDT位于内存的任何地方,它指定IDT的物理基地址及其最大长度。
中断服务子程序的入口地址相关信息在内存中的地址 = idtr CPU寄存器中的地址 + 8 × 中断向量的值 。
(5)可编程中断控制器
中断控制器是作为中断和CPU核之间的一个桥梁而存在的,每个CPU内部都有一个自己的中断控制器。可编程中断控制器,其本身有一定的寄存器,CPU可以通过操作设置中断控制器屏蔽某个中断引脚的信号,实现硬件上的中断屏蔽。
如下图,CPU的INTR与中断控制器的INT相连,INTA与ACK相连,当一个外部中断发生时(比如键盘中断IRQ1),中断控制器与CPU交互操作如下:
① IRQ1发生中断,主中断控制器接收到中断信号,检查中断屏蔽寄存器IRQ1是否被屏蔽,如果屏蔽则忽略此中断信号。
② 将中断控制器中的中断请求寄存器对应的IRQ1位置位,表示收到IRQ1中断。
③ 中断控制器拉高INT引脚电平,告知CPU有中断发生。
④ CPU每执行完一条指令时,都会检查INTR引脚是否被拉高,这里已被拉高。
⑤ CPU检查EFLAGS寄存器的中断运行标志位IF是否为1,若为1,表明允许中断,通过INTA向中断控制器发出应答。
⑥ 中断控制器接收到应答信号,将IRQ1的中断向量号发到数据总线上,此时CPU会通过数据总线读取IRQ1的中断向量号。
⑦ 最后,如果中断控制器需要EOI(End of Interrupt)信号,CPU则会发送,否则中断控制器自动将INT拉低,并清除IRQ1对应的中断请求寄存器位。
(6)关于中断OS和硬件分别完成哪些事情?
OS:初始化中断向量表;初始化中断向表寄存器(idtr寄存器);执行中断处理程序;执行中断服务子程序
硬件:不同中断源对应的中断向量值;可编程中断控制器接口
中断处理过程中软硬件职责:
硬件:保护断点;关中断。
软件:保护现场;执行中断服务子程序;恢复现场;开中断。
RTC时钟是一块时钟芯片,考电池供电,为计算机提供计时标准。
OS时钟产生于PC主板上的定时/计数芯片。
(1)时钟中断信号的产生
OS时钟硬件(可编程间隔定时器)
功能:按指定的时间间隔产生时钟中断。组成:晶振、计数器、保持寄存器
时钟中断间隔取决于保存寄存器的值。寄存器的值越小,时钟中断间隔越小,CPU月频繁处理时钟中断,内核占用CPU越多,应用程序执行速度越慢。
(2)时钟驱动程序的功能
时钟软件(时钟驱动程序)
(3)操作系统为用户提供系统时间需要哪些软硬件?
硬件:可编程中断控制器、可编程间隔定时器、CMOS时钟芯片
软件:时钟中断处理程序、中断向量表。
系统调用是一群预先定义好的模块,它们提供一条管道让应用程序或一般用户能由此得到操作系统核心程序的服务。
系统调用可以使编程更加容易,极大地提高了系统的安全性(内核代码固定)。
(1)什么是系统态和用户态
用户态执行:用户空间是指用户进程所处的地址空间,当一个进程在用户空间执行时,称该进程在用户态执行。
系统态执行:系统核心空间是指含有一切系统核心代码的地址空间,当进程处于具有执行系统核心代码的权力之
状态时,称为进程处于系统态执行。
(2)系统调用与一般函数的区别
系统调用运行在系统态;
系统调用与一般函数调用的执行过程是不同的;
系统调用要进行“中断处理”,比一般函数调用多了一些系统开销。
(3)系统调用执行过程
以Linux系统的系统调用为例说明系统调用的执行过程如下:
1)保存系统调用号
2)执行相应的特殊指令,进程陷入内核态
3)执行中断处理程序。
4)以系统调用号为索引,在系统调用表中找到系统调用实现例程的起始地址。
5)执行系统调用例程,返回用户态。
略
(1)进程同步的任务
1.在资源共享的情况下:保证诸进程以互斥的方式访问临界资源(以互斥方式访问的共享资源)——必须以互斥方式访问的共享资源;
2.在相互合作的关系中:保证相互合作的诸进程在执行次序上协调相互合作的进程协调运行。
(2)实现进程互斥的原理
进程互斥的目的是使进程以 互斥 的方式访问临界资源,只要能使进程以互斥的方式进入临界区就能够保证进程对临界资源的互斥访问。所以,可以通过在临界区前加进入区代码,在临界区后面加退出区代码来实现进程的互斥。进入区检查是否可以进入临界区并对临界区“加锁 ” 。退出区释放临界区访问权。
(3)同步机制遵循的准则
空闲让进;忙则等待;有限等待;让权等待。
(1)整型信号量是表示共享资源状态且只能由特殊的原子操作改变的整型量。
定义一个整型变量,用整型变量值来标记资源使用情况:如整型量>0,说明有可用资源;整型量≤0说明资源忙,进程必须等待。对于一次只允许一个进程访问的CS,可定义一个用于互斥的整型信号量,并被初始化为1。
整型信号量的值只能通过两个特定的原子操作wait和signal来改变
(2)整型信号量的wait和signal操作,s定义为整型信号量
var s:integer; //s为整型信号量
wait(s){ //用于申请资源
while s≤0 do no-op;
s=s-1;
}
signal(s){ //用于释放资源
s=s+1;
}
(3)整型信号量应用举例
①用整型信号量实现进程互斥
思路:为必须互斥访问的CS定义一个互斥信号量mutex,初始值为1。然后,将CS放在wait(mutex)和signal(mutex)之间,当CS可访问时,wait(mutex)才能正常结束使进程进入临界区。
{ …
wait(mutex);
临界区代码
signal(mutex);
…
}
②用整型信号量实现进程协调
有p1和p2两个进程,要求p2必须在p1结束后执行,为此可设置一个信号量s,初始值置为0,同步代码如下:
parbegin
begin p1; signal(s); end
begin wait(s); p2; end
parend
(1)记录型信号量的数据类型
Type semaphore=record
Value:integer //资源数量
L:list of process //阻塞队列,申请某个信号对应的临界资源而申请不到的进程,其进程控制块插入到该队列
end
(2)wait操作和signal操作的算法描述
procedure wait(s)
var s:semaphore
begin
s.value:=s.value-1;
if s.value<0 then block(s.L)
end.
procedure signal(s)
var s:semaphore
begin
s.value:=s.value+1;
if s.value<=0 then wakeup(s.L)
end.
(3)说明
生产者进程生产产品,并将产品提供给消费者进程消费。为使生产者进程和消费者进程能并发执行,在它们之间设置了一个具有n个缓冲区的缓冲池,生产者进程可以将它所生产的产品放入一个缓冲区中,消费者进程可以从一个缓冲区中取得一个产品消费。任意两个进程必须以互斥的方式访问公共缓冲池。当缓冲池空时,消费者进程必须等待;当缓冲池装满产品时,生产者进程必须等待。
利用记录型信号量机制写出读者-写者问题的同步算法描述
(1)信号量设置
设置一个互斥信号量mutex,用户实现对公共缓冲池的互斥访问,初始值为1;
设置两个资源信号量,分别表示可用资源数。
empty:表示缓冲池中的空缓冲区数,初始值为n;
full:表示装有消息的缓冲区数,初始值为0(一个缓冲区放一个消息)
(2)同步代码
Producer:
begin
repeat
...
produce an item in nextp;
wait(empty);
wait(mutex);
buffer(in):=nextp;
in:=(in+1)mod n
signal(mutex);
signal(full);
until false;
end
Consumer:
begin
repeat
...
wait(full);
wait(mutex);
nextc:=buffer(out);
out:=(out+1)mod n;
signal(mutex);
signal(empty);
until false;
end
(3)说明
① wait和signal操作必须成对出现
② wait操作的顺序不能颠倒,必须先对资源信号量进行wait操作,再对互斥信号量进行wait操作。(否则可能会出现死锁现象)
D是多个进程共享的数据区,允许多个进程同时读D,允许一个进程写D,写D时,不能有其它任何进程读或写D。D是共享对象。
利用记录型信号量机制写出读者-写者问题的同步算法描述
(1)信号量设置
① 全局量readcount 用于对进入共享区的读进程计数。
② rmutex用于对多个进程共享的变量readcount的互斥访问。
③ wmutex用于实现读/写互斥、写/写互斥。
(2)同步代码
writer:
begin:
wait(wmutex);
...
writing operation;
...
signal(wmutex);
end;
reader:
begin:
wait(rmutex);
if readcount=0 then wait(wmutex);
readcount++;
signal(rmutex);
...
reading file;
...
wait(rmutex)
readcount--;
if readcount=0 then signal(wmutex);
signal(rmutex);
end;
第一个进入D区的读进程需要执行wait(wmutex),申请读写互斥的信号量;最后一个退出D区的读进程需要执行signal(wmutex),释放对D区的读写互斥的信号量。
略。
正在执行的进程执行完毕;进程阻塞;正在运行的进程时间片用完;在支持抢占式调度的系统中有优先权高的进程到来;中断返回。
中断处理过程中,临界区代码执行过程中,原子操作时都不能进行进程调度。
进程调度由操作系统内核中的进程调度程序来完成。
进程调度算法是从多个就绪进程中选择一个进程并为它分配cpu的算法
选择调度算法的原则有哪些?
1)周转时间短(周转时间:从作业被提交给系统开始到作业完成为止的这段时间间隔)
2)响应时间快
3)截止时间的保证
4)系统吞吐量高
5)处理机利用率好
在作业调度中,FCFS就是从后备作业队列中,选择最先进入该队列的作业(队首作业)进行调度。在进程调度中,FCFS就是从就绪队列的队首,选择最先到达队列的进程,为该进程分配CPU。
从后备作业中选出估计运行时间最短的作业,将它们调入内存运行。
当使用优先权调度算法进行进程调度时,系统将CPU分配给就绪队列中优先权最高的进程。
非抢占式(nonpreemptive)优先权算法:进程一但得到处理机,则该进程便一直进行下去直到完成或由于某事件放弃处理机。
抢占式(preemptive)优先权调度算法:高优先权的进程可以抢占处理机,使正在执行的低优先权进程中断执行。
无穷阻塞(indefinite blocking)或饥饿(starvation)问题:低优先权进程长时间得不到调度。
老化(aging)技术:逐渐增加在系统中等待时间很长的进程的优先权。
优先权的类型分为静态优先权和动态优先权。
(1)静态优先权
静态优先权在创建时确定,在进程的整个运行期间保持不变。静态优先权值通常可以根据进程的类
型、进程需要的资源数量、用户的要求来设定。
(2)动态优先权
进程创建时被赋予的优先权,随进程的推进或随其等待时间的增加而改变。动态优先权调度算法可
以使系统获得更好的调度性能。
在采用时间片轮转调度算法的系统中,系统为进程分配一定长度的时间片,每当进程在CPU上连续运行的时间等于一个时间片长度。操作系统在时钟中断处理过程中会抢占CPU,进行进程切换,用新的就绪进程替代当前进程,被替换的当前进程重新回到就绪队列中。
在为调度程序确定时间片的大小时,通常要考虑到以下几个因素:
系统对响应时间的要求;就绪队列中进程的数目;系统的处理能力;
时间片是一个较小的时间单元,通常为10ms到100ms。
实现时间片轮转调度算法需要哪些特定硬件和软件的支持
答:需要的硬件:可编程间隔定时器、可编程中断控制器。
需要的软件:进程控制块、进程调度程序、时钟中断处理程序。
多级队列调度是根据作业的性质或类型的不同将就绪进程队列再分为若干个独立的就绪队列,各个作业固定地分属于一个队列,每个队列采用一种算法,不同的队列可采用不同的调度算法。
设多个优先权不同的就绪队列,允许进程在多个不同的就绪队列间移动
算法 | 是否会导致饥饿 | 是否可抢占 | 优点 | 缺点 |
---|---|---|---|---|
先来先服务 | 不会 | 不是 | 公平;实现简单 | 对短作业不利 |
短作业优先 | 会 | 不是 | 有效缩短作业和进程的平均等待时间,提高系统吞吐量 | 对长作业不利;难以做到真正的短作业优先 |
优先权 | 会 | 都有 | 区分优先级适用于实时系统 | 可能会导致饥饿 |
时间片轮转 | 不会 | 是 | 公平,适用于分时系统 | 频繁切换有开销,不区分优先级 |
多级队列 | 会 | 用户进程是 | 减少了进程调度的开销 | 不够灵活,可能会产生饥饿 |
多级反馈队列 | 会 | 是 | 平衡优秀 | 可能导致饥饿 |
局部性原理
时间局部性:程序中的某条指令一旦被执行,不久后该指令可能再次被执行;
空间局部性:程序一旦访问了某个单元,不久以后其附近的存储单元也将被访问。
高级语言程序必须经过编译、链接才能成为可执行程序,可执行程序必须被操作系统装入内存才能执行。
程序的装入就是系统调用装入程序将程序装入内存
(1)绝对装入方式——单道程序系统使用
编译程序事先已知程序在内存中的驻留位置,编译时产生绝对地址的目标代码,绝对装入程序按照装入模块的绝对地址将程序和数据装入内存。装入模块被装入内存后,不需对程序和数据的地址进行修改。
(2)可重定位装入
在程序装入时对目标程序中的指令和数据地址的修改过程称为重定位。
1、编译程序使目标模块的起始地址从0开始。
2、程序装入时,装入程序根据内存的使用情况将装入模块装入到内存的某个位置,并对模块进行重定位。
物理地址=有效相对地址+程序在内存中的起始地址。
(3)动态运行时装入(动态重定位)
进程在装入内存后,可能从一个内存段移动到另一个内存段(如紧凑)。在这种情况下,地址映射必须延迟到进程执行时再进行。
当进程获得CPU运行时,系统吧进程在内存的起始地址存入重定位寄存器,进程在运行过程中访存时,通过重定位寄存器的值与被访问单元的逻辑地址相加计算出出被访问单元的物理地址。
将编译后的目标模块装配成一个可执行的程序
(1)静态链接
在程序运行前,用链接程序将目标模块链接成一个完整的装入模块。
静态链接的任务:
对相对地址进行修改;
变换外部调用符号:将每个模块中所用的外部调用符号,都变换为相对地址
静态链接的特点:
1、存储开销大:无论本次运行会不会执行的程序全部都被链接到一个可执行文件中。
2、程序开发不方便:修改某一个模块会导致整个程序的重新链接
3、程序运行快
(2)动态链接
可将某些模块的链接推迟到执行时再进行。
过程略。
内存中只有一个用户区,任意时刻内存中只能装入一个程序。
这种方式用于单用户单任务的OS,它把内存分为系统区和用户区。
将内存用户区划分为若干个固定大小的区域,每个区域驻留一道程序。
划分分区的方法:
(1)分区大小相等(内存利用率低)
(2)分区大小不等
通过查看固定分区分配表(用C语言的数据结构实现)来为进程分配内存。
(1)基本原理
系统初始只有一个大空闲区,当进程请求空间时,由系统根据进程需要的空间大小划分出一片空闲区分配给进程。系统运行一段时间后,内存的空闲区可能散布在不连续的区域。系统维护一个记录当前空闲分区情况的数据结构,当进程请求内存时,系统从所有空闲区中找大小合适的空闲分区进行分配。系统中分区的大小和数量都是变化的,空闲区的大小和数量也是变化的。
(2)分区分配中的数据结构
① 空闲分区表
为每一个空闲分区建立表项。分配出去的进程,其分区信息(起始地址和分区大小)记录在PCB当中。
② 空闲分区链
为每个空闲分区建立一个分区结点;每个结点包括向前、向后指针、分区起始地址及大小。
(3)动态分区分配算法
① 首次适应算法(FF)
在采用空闲分区链作为数据结构时,FF算法要求空闲分区链以地址递增的次序链接。在进行内存分配时,从链首开始顺序查找,直至找到一个能满足其大小要求的空闲分区为止。然后,再按照作业的大小,从该分区中划出一块内存空间分配给请求者,余下的空闲分区仍留在空闲链中。
特点:高地址部分大空闲区较多;低地址部分容易留下小分区;查找从低地址开始,查找开销较大。
② 循环首次适应算法(NF)
该算法是由首次适应算法演变而形成的。在为进程分配内存空间时,不再每次从链首开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直至找到第一个能满足要求的空闲分区,并从中划出一块与请求的大小相等的内存空间分配给作业。为实现该算法,应设置一起始查找指针,以指示下一次起始查找的空闲分区,并采用循环查找方式。
特点:空闲区分布均匀;查找开销较小;容易使系统缺乏大空闲区;
③ 最佳适应算法(BF)
该算法每次为作业分配内存,总是把既能满足要求、又是最小的空闲分区分配给作业,避免了“大材小用”。为了加速寻找,该算法要求将所有的空闲区,按其大小以递增的顺序形成一空闲区。这样,第一次找到的满足要求的空闲区,必然是最优的。
特点:避免大材小用,提高内存利用率;容易留下难以利用的小空闲区。
④ 最差适应算法(WF)
将空闲分区链表中的节点按照分区由大到小的顺序排列,每次从最大的空闲分区中划分出满足进程需求的内存空间分配给进程,这样可以在每次分配时产生最大的剩余空闲分区。
(4)动态分区分配的流程
内存分配流程:检索空闲链表;找足够大空闲区(可以采用不同的动态分区分配算法);进行分配
内存回收流程:释放内存;合并空闲分区;修改空闲分区链表
如果被释放的内存区域(回收区)与任何其他的空闲分区都不相邻,则为该回收区建立一个空闲分区链表的节点,使新建节点的起始地址字段等于回收区起始地址,空闲分区大小字段等于回收区大小,根据内存分配程序使用的算法要求把新建节点插入空闲分区链表的适当位置。
合并时的三种不同情况:
① 仅回收区的前面有相邻的空闲分区;
② 仅回收区的后面有相邻的空闲分区;
③ 回收区前后哦都有相邻的空闲分区。
(1)基本概念
页面:将一个进程的逻辑地址空间分成若干个大小相等的片,称为页面或页。
物理块:将内存空间分成与页相同大小的若干个存储块,称为物理块或页框或帧。
分页存储:在为进程分配内存时,以块为单位将进程中的若干页分别装入多个可以不相邻接的块中。
页内碎片:进程的最后一页一般装不满一块,而形成不可利用的碎片,称为页内碎片。
页表:页表的作用是实现从页号到物理块号的映射。页表在内存中连续存放。
(2)基本分页存储管理方式中的地址结构
地址结构中包含两部分:页号p、页内偏移量w。若用m位表示逻辑地址,页大小为2的n次幂,则用低n位表示页内偏移量w;用高m-n位表示页号p。
若A为逻辑地址,L为页面大小,P为页号,W为页内偏移量.
P=INT(A/L)
W=mod(A/L)
已知的逻辑地址a得到相应的物理地址的过程如下:
页表长度:一个页表有几个页表项
页表项长度:一个页表项所占内存空间大小
快表(转换后援缓冲TLB),是为了提高CPU访存速度而采用的专用缓存,用来存放最近被访问过的页表项。通常TLB的条目数很有限。
TLB的条目由键值对组成,键部分是也好,值部分是该页号对应的物理块号。
对于很大的逻辑地址空间,使用分页存储,需要很大的连续空间来存放页表,为了实现页表的离散存放,引入了两级或多级页表。
(1)两级页表实现方法
将页表再进行分页,使每个页面的大小与内存物理块的大小相同,并为它们编号。将这些页表页面分别放入不同的,不一定相邻的物理块中,为离散分配的页表再建立一张页表,称为外层页表,在外层页表中的每个表项中记录了页表页面的物理块号。
(2)两级页表的寻址
假设逻辑地址为A,页大小为L,页表长度为N。
INT [ A / L ] 是表示第几个页表分页;
P1 = INT [ INT [ A / L ] / N ] 是表示页表分页在外部页表的第几项
P2 = mod [ INT [ A / L ] / N ] 是表示页表分页中的偏移量
d = MOD [ A / L ] 是表示页内偏移量
页表分页所在的物理块号在内存中的地址 = 外层页表的起始地址 + P1 × 页表项长度
进程页面所在内存中的地址 = 页表分页的起始地址 + P2 × 页表项长度
页表分页的起始地址 = 页表分页所在的物理块号 × 物理块大小
(3)多级页表
对于64位的机器,使用二级页表,仍存在连续占用大量内存的问题,可以采用多级页表结构,将外层页表再分若干页。
(1)分段
作业的地址空间被划分成若干个段,每个段定义了一组逻辑信息,每个段的大小由相应的逻辑信息组的长度确定,段的大小不一样,每段的逻辑地址从0开始,采用一段连续的地址空间。
分段的逻辑地址是二维的,由段号和段内地址组成。
(2)地址变换
段表:每个进程有一个段表,每一个段表项包含段号、段基址(段的起始地址)、段长(段大小)。
已知逻辑地址为S:d,S为段号,d为段内偏移,求物理地址的步骤为:
① 以段号S为索引,从段表中找到段号为S的段表项
S段表项起始地址 = 段表起始地址 + S × 段表项长度
段表项长度是一个段表项所占的字节数
② 从找到的段表项中读出基地址和段大小
③ 如果d小于等于段大小,则将段基址和d相加,得到该逻辑单元S:d的物理地址。
(3)分段和分页的区别
① 页是按物理单位划分的,段是按逻辑单位划分的。
② 页的大小是固定的,段的大小不固定,决定于用户编写的程序和编译器。
③ 分页的地址空间是一维的,分段的地址空间是二维的。
虚拟存储器是指具有请求调入功能和置换功能,能从逻辑上对内存容量进行扩充的一种存储器系统。在虚拟存储器系统中,作业无需全部装入,只要装入一部分就可运行。
虚拟存储技术实现的基本思路是只把进程一部分装入内存,CPU访问内存时若发现所访问的内容不在内存中,则通过中断请求将所需内容从外存调入内存,这是请求调入。调入过程中,内存不足,操作系统选择一部分内存中的内容换出岛外村,腾出空间把需要装入的内容调入内存,这是置换。
引入虚拟内存管理的目的
提高内存利用率;提高多道程序度;使程序员不用担心物理内存的容量对编程的限制。
虚拟存储管理技术实现时依据局部性原理的。
程序执行的局部性原理指出程序在执行时呈现出局部性规律,即在一较短的时间内,程序的执行仅局限于某个部分。相应地,它所访问的存储空间也局限于某个区域。局部性原理表现为时间的局部性和空间的局部性。
在支持请求分页的系统中局部性好的应用程序在执行时高速缓存命中率高、快表命中率高,缺页率低,因此程序执行过程中平均有效访存时间短,使应用程序运行的速度较快。
请求分页系统;请求分段系统
(1)请求分页中的硬件支持
① 页表机制
页表项字段:
页号:作为地址映射时的索引
物理块号:页面在物理内存中的物理块编号
状态位P:用来标识页面是否在内存中
访问字段A:用于记录页面最近被访问的情况。系统根据A的值把最近最久未被访问的页面换出到外存
修改位M:用于标识页面最近是否被修改过。若被修改过,该页面被调出内存的时候,需要把修改的页面写回外存。
外存地址:指出页面在外村中的地址
② 缺页中断机构
在访存过程中发现缺页时产生缺页中断信号。
具体过程:
Ⅰ 分页硬件通过页表完成逻辑地址转换时,检查页表中的存在位P,判断当前被访问的页是否在内存中,若不在,产生缺页中断信号;
Ⅱ 执行缺页中断处理过程,现在内存中为请求调入的页找一个空闲物理块;
Ⅲ 调度磁盘操作,把需要的页装入到空闲物理块中;
Ⅳ 修改页表
Ⅴ 重新执行因缺页而被中断的指令。(缺页中断为内部中断,可以按照与中断前完全相同的位置和地址重新执行进程)
③ 地址变换机构
1、 根据逻辑地址中的页号查找快表。
2、 若快表中无该页信息,转到内存页表中查找。
3、 若页表中的状态P显示该页已调入内存,则将该表 项写入快表,并计算物理地址。
4、若该页尚未调入内存、则产生缺页中断,请求OS从外存中把该页调入内存
(2)页面分配
① 最小物理块数
保证进程正常运行所需要的最少物理块数。它与计算 机的硬件结构有关,取决于指令的格式、功能和寻址方式。
例如:一个支持16位指令格式的机器,采用直接寻址方式,用高8位表示操作码,低8位表示操作数,如果内存单元以一个8位字节作为一个编址单元,当采用直接寻址方式时,上面的指令本身可能涉及两个页面,操作数部分的地址可能涉及第三个页面,这样的的情况下,至少要为进程分配三个物理块,才能保证进程正常执行。
如果采用间接寻址方式,操作数部分的地址指向的内存单元中存放的是另外一个地址,这时指令涉及的页面数最多可能达到四个(假设地址和数据都只占一个字节),即:指令本身可能涉及两个页面,操作数部分的地址可能涉及第三个页面,操作数地址中存放的内存地址可能涉及第四个页面。这时,系统必须为进程分配至少四个物理块才能保证进程正常执行。
② 页面分配和置换策略
固定分配局部置换;可变分配全局置换;可变分配局部置换
③ 分配算法
平均分配算法;按比例分配算法
(3)页面调入策略
① 何时调入
预先调入页面:将预计不久之后会被访问的页,预先调入内存。
②从何处调入页面
1、对换区调入:对换空间足够大,进程运行前,将相关文件从文件区拷贝到对换区,发生缺页请求时,从对换区调入缺页。
2、从文件区调入:对不会修改的页,从文件区调入;可能被修改的部分,换出时写入对换区,再换入时,从 对换区调入。
3、Unix方式:与进程有关的文件都放在文件区,凡是未运行过的页面都应该从文件区调入,曾经运行过又被换出的页面从对换区调入 。
对换区比文件区的调度页面速度快
(1)最佳置换算法
1、 策略:将未来最长时间内不再被访问的页换出。
2、 缺点:不可实现。
3、 优点:换页率最低。
(2)先进先出页面置换FIFO
1、策略:最先进入内存的页最先被淘汰。
2、实现:采用一个先进先出队列。
3、缺点:无法保证常用页面不被换出,导致较低的效率。
4、优点:实现简单。
(3)最近最久未使用置换算法LRU
1、策略:最近最久未使用的页面淘汰。
2、实现
① 寄存器
② 栈
③ 计数器
为每个页表项增加一个时间字段,并为CPU增加一个逻辑时钟或计数器。每次访问内存某个页面时,就将时钟寄存器的值赋给这个页面对应的页表项的时间字段,每次置换时选择时间字段值最小的页面作为换出页面。
(4)Clock算法
简单的CLOCK算法实现方法:为每个页面设置一个访问位,再将内存中的页面都通过链接指针链接成一个循环队列。当某页被访问时,其访问位置为1。当需要淘汰一个页面时,只需检查页的访问位。如果是0,就选择该页换出;如果是1,则将它置为0,暂不换出,继续检查下一个页面,若第一轮扫描中所有页面都是1,则将这些页面的访问位依次置为0后,再进行第二轮扫描(第二轮扫描中一定会有访问位为0的页面,因此简单的CLOCK算法选择一个淘汰页面最多会经过两轮扫描)
(5)页面缓冲算法
采用可变分配和局部置换方式,置换算法采用的是FIFO。算法规定如果被淘汰的页面未被修改,就将它直接放入空闲链表中,否则,便放入已修改页面的链表中。页面在内存中并不做物理上的移动。
空闲页面链表实际上是一个空闲物理块链表。
(1)缺页率对有效访问时间的影响
有效访问时间:成功访存所用的时间。假设P为缺页率,ma为存储器访问时间
有效访问时间 = (1-P)× ma + P × 缺页中断时间
缺页中断事件 = 缺页中断服务时间 + 却也读入时间 + 进程重新执行时间
(2)工作集
程序在运行时对页面的访问是不均匀的;即往往在某段时间内的访问仅局限于较少的若干个页面,而在另一段时间内,则又可能仅局限于对另一些较少的页面进行访问,若能预知程序在某段时间间隔内要访问哪些页面,并能将它们提前调入内存,将会大大地降低缺页率,从而减少置换工作,提高CPU的利用率。
工作集:在某段时间间隔△里,进程实际要访问的页面集合。要使缺页少发生,必须使程序的工作集全部在内存中。
W(t, △) 工作集的窗口:
△又叫工作集的窗口尺寸, △太大,影响存储器利用率。
△太小,缺页率高,降低系统吞吐量。
程序运行的过程中,运行到不同的时刻,需要访问的页面不同。
**Windows NT****的页面分配策略:
① 采用请求调页
② 进程被第一次创建时,为进程指定了一个最小工作集和一个最大工作集。最小工作集,是进程正常运行需要调入内存的最小页面数。当内存有足够的空间时,可以为进程分配足够的空间以装入它的最大工作集。
③ 当某进程在内存中的页面数 < 最大工作集时,若发生缺页,系统从空闲页队列中取一空页面分配给该进程。当某进程在内存中的页面数 = 最大工作集时,若发生缺页,系统从该进程的页面中按FIFO的原则,淘汰一个该进程的页面。
④ 当空白的页面队列中空闲页的数量减到一个最低值时,系统检查所有进程,对工作集 > 最小工作集的进程,淘汰该进程的一些页,使该进程的工作集 = 最小工作集。
(3)抖动
多道程序度太高,使运行进程的大部分时间都用于进行页面的换入、换出,而几乎不能完成任何有效的工作的状态称为抖动。
原因:系统中进程数量太多,每个进程能分配到的物理内存快太少,以至于进程运行过程中频繁请求调页和页面置换。
文件命名;文件结构;文件类型;文件存取;文件属性;文件操作。
文件系统提供目录用于记录文件,在很多系统中目录本身也是文件。
目录通常包含有许多目录项,每个目录项对应一个文件。在目录项结构中,每个目录项包含文件名、文件属性和文件数据在磁盘上的地址。在 i 节点结构中,目录项中会有一个文件名和一个i节点号,文件属性和磁盘地址就放在i节点中。
实现文件存储的最重要问题是记录各个文件分别用到哪些磁盘块。文件系统以逻辑磁盘块(簇,2的n次方个连续扇区)为单位进行分配。
(1)连续分配
把每个文件作为一连串连续数据块存储在磁盘上。
优点:简单易实现,记录每个文件用到的磁盘块仅需一个数字,即第一块的磁盘地址。性能好,一次操作,可读出整个文件。
缺点:无法知道该为文件分多少空间,文件长度是会变的,造成磁盘碎片。
(2)链接表分配
为每个文件构造磁盘块的链接表,每个块的第一个字用于指向下一块的指针,块的其它部分存放数据。在目录项中只需存放第一块的磁盘地址,文件的其它块可以根据这个地址来查找。
优点:磁盘空间利用率高,管理简单。
缺点:随机存取的速度慢。
(3)使用索引的链接分配
使用方法二的方法实现文件,取出每个磁盘块的指针字,把它放在内存的表或索引中。随机查找时,顺着链查找磁盘块,但只需查找内存中的链表,不需访问磁盘。同以前的方法一样,不管文件有多大,在目录项中只需记录一个整数,根据它可以找到文件的所有块。MS-DOS就使用这种方法进行磁盘分配。
如下图所示
优点:比(2)速度快
缺点:必须把整个表都放入内存中,很显然不适合大容量的磁盘。
(4)i 节点
给每个文件赋予一张称为i节点的小型表其中列出了文件属性和各块在磁盘上的地址,对于大文件,由于包含的磁盘块数很多,可以在i节点中存放一次间接地址,或二次间接地址,或三次间接地址。UNIX中使用这种分配方案。
打开文件时,操作系统通过用户给出的路径名找到相应的目录项。目录系统的主要功能是把ASCⅡ文件名映射成查找文件数据所需的信息。
(1)CP/M中的目录
CP/M中只有一层目录,因此只有一个目录(文件),查找文件名,就是在这个唯一的目录中找到文件对应的目录项,从目录项中获得文件存放的磁盘地址。
(2)MS-DOS中的目录
每个目录项占32个字节,包含文件名、文件属性、和第一个磁盘块号,根据第一个磁盘块的块号,可以找到所有的文件块。MS-DOS是树型目录(层次型目录)。块号从0~216最多有64K个块,若每块0.5K,则可支持32M的磁盘空间,每块1K,可支持64M磁盘空间。
MS-DOS目录项如图,
目录表项包含了第一个文件块的编号,这个编号用作FAT索引,沿着这条链所有的块都能找到。
FAT文件系统的不同版本取决于磁盘地址包含多少二进制位,如FAT-12,FAT-16和FAT-32。
FAT-12完成按名访问 的过程是:文件系统的目录项中存有文件名和文件的第一个数据块在磁盘中的簇号。在FAT表中存有后续数据块在磁盘中簇号。 FAT12文件系统先以文件名为索引搜索目录,找到相应的目录项后获取文件第一个数据块在磁盘中的簇号。根据第一个数据块在磁盘中的簇号从FAT表中可以找到文件的其他所有数据块的簇号。
(3)Unix中的目录
UNIX中使用的目录结构非常简单,每个目录项只包含一个文件名及其i节点号。有关文件类型、长度、时间、拥有者和磁盘块等所有信息都放在i-节点中 。当查找文件时先找到该文件的 i 节点存放的位置,再从i节点中找 到该文件的磁盘块号。
(1)块大小
给文件分配块太大,浪费磁盘空间,块太小,查找一个文件多次寻道,浪费时间。一般磁盘块大小是2的整数次幂个连续的扇区。一般选择的块大小在512字节,1K或2K。若扇区大小为512个字节,磁盘块的大小选定为1K,则文件系统读写两个连续的扇区,并把它们看成不可分割的单元。
(2)记录空闲块
① 空闲磁盘块链表
用一些空白磁盘块存放空闲磁盘块块号。一个磁盘块存放尽可能多的空闲盘块号,并专门留出最后几个字节存放指向下一个存放空闲盘块号的磁盘块的指针 。
② 位图
磁盘被划分成n块,用n位位图表示磁盘块使用情况,每一位代表一个盘块,该位为1表示磁盘空闲,该位为0表示磁盘已分配。
(1)定义:
① 设备控制器是CPU与I/O设备之间的接口,接受I/O的命令并控制I/O设备完成工作。
② 设备控制器是一个可编址设备:连接多个设备时可有多个设备地址。
(2)设备控制器的功能
① 接收和识别命令:接收CPU的命令和参数,存放在控制器的控制寄存器中,并对命令和地址译码。
② 数据交换:通过数据寄存器进行数据交换。
③ 设备状态的了解和报告:有专门存放设备状态信息的寄存器和触发器。
④ 地址识别:设备控制器必须能识别他所控制的每个设备的地址。
⑤ 数据缓冲:设备控制器中可以存储数据,作为CPU和I/O之间的缓冲
⑥ 差错控制:当通过数据校验发现数据传输出错时,可以报告CPU。
(3)设备控制器组成
① 设备控制器与处理机的接口:数据线、控制线、地址线。
② 设备控制器与设备的接口:设备与设备控制器中的三类信号为数据信号、控制信号、状态信号。
数据信号:设备与设备控制器相互传递。
控制信号:由控制器传给设备,用于规定设备执行读或写操作的信号。
状态信号:用于指示设备的状态,如硬盘有坏块、硬盘准备好、正在执行命令的信号等。
③ I/O逻辑
I/O逻辑主要由指令译码器和地址译码器两部分功能部件构成,将CPU的命令和地址分别译码,控制指定设备进行输入输出。
(4)设备驱动程序
设备驱动程序是I/O进程与设备控制器之间的通信程序。设备驱动程序中包括了所有与设备相关的代码,是数据结构与函数的集合。每个设备驱动程序只处理一种设备,或者一类紧密相关的设备。
(1)轮询控制方式
主机在试图发送I/O控制命令之前先反复检测设备控制器状态寄存器的忙/闲标志位,若设备忙,则主机继续检测该标志位,直到该标志位为“空闲”,然后发送I/O指令。
(2)中断控制方式
CPU执行程序的过程中,发出输入输出请求,若此时I/O设备忙,则进程阻塞等待。当处于忙状态的设备工作完毕,通过中断控制器发出中断请求信号,CPU响应中断,执行对应该设备的中断处理程序,然后唤醒因等待该设备而被阻塞的进程。CPU继续执行这个进程时向设备控制器发出I/O指令,接着CPU被调度程序分配给某个进程,继续执行程序。当本次I/O结束,设备控制器向CPU发送中断请求信号告知CPU本次数据传输结束。
中断方式使CPU与I/O设备并行工作,提高了CPU的利用率和系统的吞吐量。采用中断方式,每次只能传送一个字节的数据,传输完一个字节就需要CPU执行一次中断处理,较多的中断处理会消耗CPU时间。
(3)DMA控制方式
DMA(Direct Memory Access 直接存储器存取)
与“中断驱动方式”相比有这样几个改进:
① 数据的传送单位是“块”。不再是一个字、一个字的传送;
② 数据的流向是从设备直接放入内存,或者从内存直接到设备。不再需要CPU作为“快递小哥”。
③仅在传送一个或多个数据块的开始和结束时,才需要CPU千预。
DR (Data Register,数据寄存器)∶暂存从设备到内存,或从内存到设备的数据。
MAR(Memory Address Register,内存地址寄存器)∶在输入时,MAR 表示数据应放到内存中的什么位置;输出时MAR表示要输出的数据放在内存中的什么位置。
DC (Data Counter,数据计数器):表示剩余要读/写的字节数。
CR (Command Register,命令/状态寄存器):用于存放CPU发来的I/O命令,或设备的状态信息。
DMA控制从磁盘读数的过程
设备控制表DCT;控制器控制表COCT;通道控制表CHCT;系统设备表SDT。
设备独立性:应用程序独立于具体使用的物理设备。
实现设备独立性带来的好处
①用户程序与物理的外围设备无关,系统增减或变更外围设备时不需要修改应用程序。
②易于处理输入输出设备的故障。
设备独立软件的功能:
①执行所有设备的公有操作:(独占设备的分配与回收、将逻辑设备名映射为物理设备名、对设备进行保护、缓冲管理、差错控制)
②向用户层(或文件层)软件提供统一的接口。(如:对各种设备的读操作在应用程序中都使用read)
为了实现设备独立性,引入逻辑设备和物理设备的概念。在应用程序中,使用逻辑设备名来请求使用某类设备,系统在执行时必须使用物理设备名称。逻辑设备名到物理设备名的映射实现:
设置一张逻辑设备表LUT(logical Unit Table),在该表的每个表目中包含三项:逻辑设备名、物理设备名、设备驱动程序的入口地址。LUT的设置可以采用两种方式,即整个系统设置一张LUT或者每个用户设置一张LUT。
(1)寻道时间Ts:把磁头移动到指定磁道上所经历的时间。该时间使启动磁头的时间s与磁头移动n条磁道所花费的是时间之和:Ts = m × n + s。m使一个常数,与磁盘驱动器的速度有关。
(2)旋转延迟时间Tr:指定扇区移动到磁头下面所经历的时间。
(3)传输时间Tt:把数据从磁盘读出或向磁盘写入数据所经历的时间。Tt = b / (r*N) r为磁盘每秒钟的转数,N为一条磁道上的字节数。b为每次读或写的字节数。
Tr和Tt是由硬件确定的,操作系统不可改变;Ts可以由操作系统改变
通过减少寻道的次数,保证各个进程对磁盘的平均访问时间最短。
(1)先来先服务
根据进程请求访问磁盘的先后次序进行调度。
(2)最短寻道时间优先
要求访问的磁道与当前磁头所在的磁道距离最近。
缺点:该方法可能会产生饥饿。
(3)SCAN算法
磁臂从磁盘的一端向另一端移动,同时当磁头移过每个柱面时,处理位于该柱面上的请求,当磁头到达另一端时,磁头改变移动方向,继续处理,磁头在磁盘上来回扫描。
缺点:某些进程等待时间可能会很长,还可能出现磁臂黏着(某些进程)。
(4)循环扫描方法
磁臂从磁盘的一端向另一端移动,同时当磁头移过每个柱面时,处理位于该柱面上的请求,当磁头移到另一端时,立即返回到磁盘开始处,返回时不处理请求。
内存的一块存储空间用来暂存从磁盘中读出的一系列盘块中的信息。高速缓存是一组逻辑上属于磁盘,物理上驻留在内存中的盘块。
(1)提前读:系统根据用户请求读的内容,把预计最近也可能要读的内容与现在要读的内容一起提前读入内存。
(2)延迟写:在支持请求分页的虚拟存储管理中,对修改过的换出页面,再把页面标记为换出页面时并不马上把页面内容写入磁盘,而是暂时保留在内存中,直到这些页面所在的物理块要被使用,导致页面内容将被覆盖的最后时刻才启动磁盘操作,把修改过的一个或若干页面写入磁盘。
(3)优化物理块布局:把一个文件放在同一个磁道或者相邻的磁道上。
(4)虚拟磁盘。
原因:竞争共享资源;进程推进顺序不当。
必要条件
① 互斥条件
② 请求和保持条件
③ 不剥夺条件
④ 环路等待条件
通过保证死锁必要条件中至少一个条件不成立
(1)摒弃:请求和保持“条件”
①实现方法:进程一次性申请整个运行过程中的全部资源,只有申请到全部资源后,方可投入运行,运行期间不再提出资源要求。
②缺点:资源严重浪费,进程延迟运行。
(2)摒弃:“不剥夺”条件
①方法:一个已保持了某些资源的进程,当它再提出新的资源要求而不能立即得到满足时,必须释放它已经保持的所有资源。
②缺点:实现复杂而且代价高 。
(3)摒弃:“环路等待”
①方法:“规定进程必须按资源排序的秩序依一定顺 序申请资源。
②缺点:限制了新设备的增加。系统为资源分配的序号与进程实际使用资源的 顺序不同而造成资源浪费。给用户编程带来了麻烦。
当系统找到一个进程执行序列,使系统只要按此序列推进进程时,可以保证进程的资源分配和顺利完成,不会发生死锁,这种状态称安全状态 。若系统不存在这样的安全序列,则称系统为不安全状态。
避免进程死锁的实质在于如何使系统不进入不安全状态。
算法的基本思想:一个进程提出请求后先试分配,然后检测本次的分配是否使系统处于安全状态,安全则按试分配方案分配资源,否则不分配。
数据结构:
长度为m的一维数组Available表示还有多少可用资源
nm矩阵Max表示各进程对资源的最大需求数
nm矩阵Allocation表示已经给各进程分配了多少资源
Max- Allocation = Need矩阵表示各进程最多还需要多少资源
用长度为m的一位数组Request表示进程此次申请的各种资源数
work是一个大小为m的一维数组,进行安全性检测过程时被初始化为当前的available
finish是大小为n的一维数组,进入安全性检测过程时,对于所有的i = 1 - n , finish[i] = false
银行家算法步骤:
①检查此次申请是否超过了之前声明的最大需求数
②检查此时系统剩余的可用资源是否还能满足这次请求
③试探着分配,更改各数据结构
④用安全性算法检查此次分配是否会导致系统进入不安全状态
安全性算法步骤:
检查当前的剩余可用资源是否能满足某个进程的最大需求,如果可以,就把该进程加入安全序列,并把该进程持有的资源全部回收。不断重复上述过程,看最终是否能让所有进程都加入安全序列。
例:
考虑下面的一个系统在某一时刻的状态:
(1)need矩阵的内容是怎么样的?
need = max - allocation
need矩阵的内容:
–P0:0 0 0 0
–P1:0 7 5 0
–P2:1 0 0 2
–P3:0 0 2 0
–P4:0 6 4 2
(2)系统是否处于安全状态?
系统处于安全状态。
work = available=(1,5,2,0)
finish[0-4]=false;
a.因为need0 < work并且finish[0]=false;所以finish[0]=true;work=work+allocatiortyn0=(1,5,3,2)
b.因为need2 < work并且finish[2]=false;所以finish[2]=true;work=work+allocation2=(2,8,8,6)
c.因为need3 < work并且finish[3]=false;所以finish[3]=true;work=work+allocation3=(2,14,11,8)
d.因为need4 < work并且finish[4]=false;所以finish[4]=true;work=work+allocation4=(2,14,12,12)
e.因为need1 < work并且finish[1]=false;所以finish[1]=true;work=work+allocation1=(3,14,12,12)
至此finish[0-4]=true,找到安全序列
(3)如果进程p1提出资源请求(0,4,2,0),这个请求能否立刻
被满足?
p1提出资源请求(0,4,2,0)
①.request1 < need1 && request1 < available
所以资源试分配:
available -= request=(1,1,0,0)
allocation1 += request=(1,4,2,0)
need -= request=(0,3,3,0)
②.进行安全性检测
work = available=(1,1,0,0)
finish[0-4]=false;
a.因为need0 < work并且finish[0]=false;所以finish[0]=true;work=work+allocation0=(1,1,1,2)
b.因为need2 < work并且finish[2]=false;所以finish[2]=true;work=work+allocation2=(2,4,6,6)
c.因为need3 < work并且finish[3]=false;所以finish[3]=true;work=work+allocation3=(2,10,9,8)
d.因为need4 < work并且finish[4]=false;所以finish[4]=true;work=work+allocation4=(2,10,10,12)
e.因为need1 < work并且finish[1]=false;所以finish[1]=true;work=work+allocation1=(3,14,12,12)
至此finish[0-4]=true,找到安全序列
故请求能立刻被满足。