前言:
1.本文件仅对部分知识点进行归纳及通俗易懂地讲解、对部分题型应试技巧进行总结,如有错误,欢迎指正。
2.本文件内容对应教材为:操作系统教程(第五版),作者:费翔林 / 骆斌
3.如需要笔者完整复习笔记请联系笔者。*
撰写本文的初衷是想记录一下本课程考试中复习总结的一些技巧、重点以及对一些复杂概念的通俗理解(方便记忆)。
1. 操作系统概论
1.1 三种管理资源技术
-
复用:本质上是操作系统让众多进程共享物理资源 -> 强调“共享操作”
-
虚拟:本质上是将一个物理资源变成单个逻辑上的对应物,创建无需共享多个独占资源的假象。
虚拟与复用的区别:复用是分割实际的物理资源,虚拟是实现假想的虚拟同类资源。
-
抽象:“对内封装实现细节,对外提供应用接口”
1.2 三个最基础的抽象
- 进程抽象:程序在处理器上被执行的抽象。
- 虚存抽象:程序在内存上的抽象。
- 文件抽象:程序在**磁盘(设备)**上的抽象,通过文件字节映射到存储设备物理块中实现。
Q:进程在实际主存中方可运行,那么在磁盘上的应该怎么办?异常访问又应该如何处理?
A:从磁盘上将其调入实际内存即可;异常处理一般涉及缺页异常等算法。
1.3 多道程序设计
定义是允许多个作业(程序)同时进入计算机系统的内存并启动交替计算的算法。
多道程序设计计算:
-
处理器/CPU上的时间 ÷ 一个周期的时间 = 处理器/CPU的使用效率
-
设主存中有 n n n 道程序,程序 I / O I/O I/O 操作时间占其运行时间比例 p p p
CPU利用率 = 1 - pn (pn 表示至少发生一次 I / O I/O I/O 操作)
1.4 操作系统类型
-
批处理操作系统
将有一批作业提交给操作系统后不再干预(不具备交互性),有操作系统控制自动运行。
-
分时操作系统
通过将CPU运行时间分成若干片段来实现轮流服务的效果。
-
实时系统
导弹制导、飞机自动驾驶等才会采用。
1.5 系统调用
定义:系统中各共享资源都交由操作系统统一掌管,因此用户程序中凡是与资源有关的操作都需要通过系统调用的方式向操作系统提出服务请求,由操作系统代为完成。
简单来说,系统调用就是一种特殊的接口,这个接口是应用程序获取操作系统服务的唯一路径。
Q:什么是API?
A:API是一个函数定义,是应用程序获取操作系统服务的唯一路径。
Q:试述API、库函数和系统调用的关系?(课后原题)
A:系统调用只是API中的一部分内容,API是将复杂的特殊接口(系统调用)封装起来,而用户可以通过C库函数调用API。
1.6 操作系统内核结构分类
单体式结构、层次式结构此处不多赘述。感兴趣的可以参考本文前言第三点。
- 微内核结构:通常采用客户/服务器模式,它并不是完整的操作系统,只是为构建操作系统提供了重要的基础。其定义是:仅将所用应用必须功能放在内核。(移植性、可扩充/修改的空间大)
2. 处理器管理
2.1 处理器状态转换
处理器一共有两种状态:核心态(也叫特权状态、系统模式和管态),用户态(也称目标状态、用户模式和目态)
Q:如何标识处理器状态?
A:可以联系计算机硬件基础的知识,一般使用处理器状态标志来作标识。
处理器状态展示(此处就用户态 -> 核心态进行说明)
- 程序请求操作系统服务并执行系统调用。
- 在程序运行时产生中断/异常,运行程序中断并转向中断/异常处理程序工作。
可以看到,转换操作需要通过中断机制发生,中断/异常为用户态 -> 核心态转换的唯一途径。
2.2 PSW程序状态字
PSW的主要作用为:实现程序状态的恢复和保护。
每个程序都有一个相关的PSW,每个处理器均舍友PSW寄存器。
2.3 中断知识
在中断时间发生后,中断装置能改变处理器内操作的执行程序。
- 硬中断(设计硬件):分为外中断和内中断。
- 软中断(软件模拟):信号机制(内核对进程进行中断),软件中断(软件+硬件结合)【书本上还以分上下半部分处理为例,需要注意上半部分是在关中断的环境下运行,主要工作是“标记中断”】
Q:中断和异常的区别
A:中断是由与现行指令无关的中断信号触发的,在系统中断上下文执行。(特征:与CPU异步,不可被打断,优先级高,可嵌套)
异常是由处理器正在执行指令引起的,通常发生在用户态(除了缺页异常),在当前进程上下文中执行。(特征:与CPU同步,可被打断,优先级低)
2.4 进程的三态和七态模型
- 三态模型:
- 七态模型:
2.5 进程映象
定义为某时刻进程内容及其状态集合称为进程映象。
这部分还有关于进程映象的结构、进程上下文、PCB的内容,感兴趣的可以参考本文前言第三点。
2.6 线程
定义为进程中可并发执行的实体,是进程的组成部分,是处理器调度和恢复的基本单位。
这部分还有关于三级进程调度(作业调度、内存调度和进程调度)的内容,感兴趣的可以参考本文前言第三点。
2.7 处理器调度算法
-
作业周转时间:t = t f i n i s h − t s u b m i t t_{finish} - t_{submit} tfinish−tsubmit = 等待时间 + 运行时间
平均周转时间:t = ( ∑ t i ) / n (∑t_i)/n (∑ti)/n
带权周转时间: w i = t i / t k w_i = t_i / t_k wi=ti/tk,其中 t i t_i ti为周转时间, t k t_k tk为运行时间
平均带权周转时间: w = ( ∑ w i ) / n w=(∑w_i)/n w=(∑wi)/n
-
各调度算法特点及相应做题技巧
调度算法 | 特点 | 相关题目做题技巧 |
---|---|---|
FCFS | 非抢占,关注等待,忽略计算时间 | |
SJF | 忽视等待,可能导致饥饿现象(不公平),通常提供作业运转时间信息 | 画时间线,在每个时间节点上查看不同作业情况,不需画表格 |
SRTF | 抢占式 | 画表格会清晰很多,每行一个作业,每列一个时间单位 |
HRRF | 每次执行作业后计算其他作业的响应比,选择最大值继续执行 | 响应比 = 周转时间 / 运行时间,结果肯定大于1 |
RR | 需要知道确切的时间片大小 |
3. 同步通信和死锁
3.1 临界区
四个原则:忙则等待,空闲让进,有限等待,让权等待。
定义:并发进程重要与共享变量有关的程序段。
3.2 临界区保护方法
3.2.1 Peterson算法(孔融让梨)
如题所示,一般我们将这个算法类比为孔融让梨,这个算法只适用于两个进程。
cobegin
process P0( ) { process P1() {
inside[0]=true; // inside[1] = true;
turn=1; //请P1进入临界区,让梨 turn = 0; //请P0进入临界区,让梨
while(inside[1]&&turn==1); while(inside[0]&&turn==0);
{临界区}; {临界区}
inside[0]=false; inside[1]=false;
} } coend
3.2.2 关中断
既然中断引起进程切换,那么直接干脆让进程运行得到保证就好了
3.2.3 测试并设置指令
- TS指令
TS指令处理过程:
bool TS(bool &x) {
if(x) {
x=false;
return true;
}
else
return false;
}
TS指令实现进程互斥:
bool s=true; //没有进程在临界区内
cobegin
process Pi( ) { //i=1,2,...
while(!TS(s)); //上锁
{临界区};
s=true; //开锁
}
coend
【笔者理解】 s = t r u e s=true s=true,意味着资源可用。 T ( s ) = t r u e T(s)=true T(s)=true,意味着上锁成功。先看互斥代码,一开始 s = t r u e s=true s=true这意味着资源此时可用,新来的进程遇到 w h i l e ( ! T S ( s ) ) while(!TS(s)) while(!TS(s))会跳出循环,容许它进入临界区,并将 s s s修改位 f a l s e false false;当该进程还占据着临界区时,其他新的进程来,发现 s = f a l s e s=false s=false资源被占用, T S ( s ) = f a l s e TS(s)=false TS(s)=false,锁也打不开,他们就会在 w h i l e ( ! T S ( s ) ) while(!TS(s)) while(!TS(s))中不断循环,直到占据着共享资源 s s s的进程不再占据该资源,并将 s = T S ( s ) = t r u e s=TS(s)=true s=TS(s)=true时获取资源。
-
对换指令
void SWAP(bool &a,bool &b) { bool temp=a; a=b; b=temp; } //对换指令实现进程互斥 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操作
设 s s s为一个记录型数据结构,一个分量为整形量 v a l u e value value,另一个为信号量队列 l i s t list list,P和V操作原语的定义如下:
P(s):将信号量 s − 1 s-1 s−1,若结果小于0,调用P(s)的进程设为等待信号量 s s s的状态,将其加入队列 l i s t list list。
V(s):将信号量s+1,若结果不大于0,从 l i s t list list中取一个等待信号量并释放。
若 s s s为正值,代表 s s s对应还可以使用的资源数; s s s为负值
简单来说,P(s)就是等待一个信号的行为,V(s)是释放一个信号的行为。
3.3.1 哲学家问题
问题解释:五个哲学家围坐在一圆桌旁,桌中央有一盘通心面,每人面前有一只空盘,每两人之间放一把叉子。每个哲学家思考、饥饿、然后吃通心面。为了吃面,每个哲学家必须获得两把叉子,且每人只能直接从自己左边或右边去取叉子。
这类问题一共有三种方法:
-
最多允许4个人一起吃
-
分奇偶:奇数编号的人先拿左叉子,后拿右叉子;偶数编号的人先右后左(画个图模拟一下方便理解)
-
取叉子的过程不容打断 -> 做法:加一个互斥信号量 m u t e x mutex mutex(有人在取叉子就先等待)
3.3.2 生产者消费者问题
问题解释: 有 n n n个生产者和 m m m个消费者,连接在一个有 k k k个单位缓冲区的有限缓冲上。 p r o d u c e r producer producer和 c o n s u m e r consumer consumer都是并发进程,只要缓冲区未满, p r o d u c e r producer producer生产的产品就可投入缓冲区;只要缓冲区不空, c o n s u m e r consumer consumer就可从缓冲区取走并消耗产品。
item B[k];
semaphore empty; empty=k; //初始化,一开始空的可以使用的缓冲区数为k
semaphore full; full=0; //初始化,一开始缓冲区内可以使用的产品为0
semaphore mutex; mutex=1; //互斥信号量
int in=0; //设置缓冲区指针
int out=0;
cobegin
process producer(i){ process consumer(i){
while(true) { while(true) {
produce(x);//生产产品 P(full); // 为空则休眠,等待至少一个产品可用
P(empty); //为满休眠,等至少一个缓冲区可用 P(mutex);
P(mutex);//互斥缓冲区 x = B[out];//取产品
B[in] = x;//将x放入缓冲区 out=(out+1)%k;//更新指针
in=(in+1)%k;//更新指针 V(mutex);
V(mutex);//释放缓冲区访问控制 V(empty);//更新可用缓冲区数量
V(full);//更新可用产品数 consume(x);//消费产品
} }
} }
coend
3.3.3 读者写者问题
问题解释:共享一个文件,多个读者同时操作,一个写者操作,写者未写完读者不能读,写者执行写操作前,已有写者和读者要全部退出。
这类问题一般分两类:读者优先和写者优先(这里暂不介绍兼顾读写的PV操作)
- 读者优先
- 写者优先
3.3.4 理发师问题
问题解释:有一位理发师,一把理发椅和 n n n把候理椅
(技巧总结)如何快速撰写PV操作伪代码:
先写 c o b e g i n cobegin cobegin和 c o e n d coend coend间的内容(拟定大概框架),明确各进程在等待什么?需要得到什么资源的释放?
确认需要什么信号量:互斥信号量(一次服务几个对象?)、同步信号量(初值多少?)
完善代码,填上答卷
3.4 进程通信
3.4.1 死锁
定义:两个进程分别等待对方所占有的一个资源,导致两者永远处于等待状态。
产生条件:
- 互斥:互斥使用资源
- 占有和等待:等待时不释放
- 不剥夺:资源只由宿主释放
- 循环等待:存在一组进程循环等待资源
3.4.2 银行家算法(画两个表)
名称 | 对应内容 |
---|---|
A v a i l a b l e Available Available | 可利用资源数量,初值为系统每类资源总数 |
M a x / C l a i m Max/Claim Max/Claim | 每个进程对每类资源的最大需求量 |
A l l o c a t i o n Allocation Allocation | 每个进程已分配资源数量 |
N e e d Need Need | 每个进程尚需要的每类资源数量( N e e d = M a x − A l l o c a t i o n Need=Max-Allocation Need=Max−Allocation) |
例题: T 0 T_0 T0时刻下有五个进程 P 0 − P 4 P_0-P_4 P0−P4和三类资源{A, B, C},各资源量分别为10,5,7
-
情况表(通常来说这个表不会直接给出来,需要进行一定的计算)
现在“3 2 2”能够满足的 n e e d need need为 P 1 P_1 P1,那么可以构造以下判断表:
-
判断表
得证< P 1 , P 3 , P 4 , P 2 , P 0 P_1,P_3,P_4,P_2,P_0 P1,P3,P4,P2,P0>为安全序列。
(技巧总结)如果是考察银行家算法,一般来说任何这方面问题其实都是转化成求安全序列的过程:
Q: t 0 t_0 t0时刻是否安全? -> 找一个安全序列,证明是安全的。
Q:进程发出 r e q u e s t ( x y z ) request(x y z) request(xyz),系统能否将资源分配给他?
3.5 其他内容
3.5.1 原子操作
定义:保证执行中的内容不被打断的重要途径。多线程环境中保持数据一致性的手段。
3.5.2 自旋锁
定义:采用忙等待思想设计。县城会一直循环检测锁状态,直到获取到锁为止。(是否回忆起了TS操作?)
4. 存储管理
有关程序链接方法、重定位、碎片的定义(内部碎片、外部碎片)、主存不足管理技术、虚拟存储、MMU(主存管理单元)等内容此处不过多赘述,感兴趣的可以参考本文前言第三点。
4.1 分页存储管理
-
逻辑地址 = 页号 + 页内位移
物理地址 = 页框号 + 页内地址 = 页框号 * 页大小 + 页内位移 = 页框号 && 页内位移
-
页表:放在内存中的,使用动态重定位技术给每个页面设立重定位(值)的集合。
-
多级页表:系统为每个进程创建了一个目录页表,他的每个表项对应一个页表页,页表页每个表项给出了页面和页框的对应关系。
例题:
-
反置页表:在快表的基础上(即反置页表是放在内核空间中的)使用了哈希,防止页表占存过大,释放内存压力。主要改进是为 I P T IPT IPT每个表象增加了一个链表指针,多了个进程标识符。
简单来说,就是能够通过物理地址查虚拟地址。
-
分页和分段的区别:
分页是用户不可见的,是信息物理单位;分段是用户可见的,是信息逻辑单位(段内必定连续,段间未必连续)
4.2 缺页中断率
页面替换算法 | 做题技巧 | 补充内容 |
---|---|---|
OPT(最佳页面替换算法/理想算法) | 画辅助队列:判断未来一段时间内哪个页框内容最迟才出现,替换他 | 容易导致 B e l a d y Belady Belady异常:增加页框但是缺页率还是上升 |
FIFO(先进先出替换算法) | ||
LRU(最近最少使用算法) | 画辅助栈:标明规定数量页框中最近最少使用的值 | |
时钟页面替换算法 | 先 r = 0 , m = 0 r=0,m=0 r=0,m=0→ r = 0 , m = 1 r=0,m=1 r=0,m=1→ r = 0 , m = 0 r=0,m=0 r=0,m=0→ . . . ... ...,其中 r r r是引用位, m m m是修改位 |
5. 设备管理
5.1 I/O软件的四个层次(自底向上)
I/O中断处理程序 -> I/O设备驱动程序(将请求转换成具体形式) -> 独立于设备的I/O软件 -> 用户空间I/O软件
5.2 四种I/O控制方式
- 轮询:使用查询指令测试设备控制器忙线状态位,决定是否可以交换数据,若不能则重复查询至可以交换为止。
- 中断:CPU部分解放,由设备控制器控制数据传输。
- DMA方式:内存与设备数据传送无需CPU干预,但仍然需要占用系统总线。
- 通道:CPU只需要处理I/O结束事件,其余工作由通道完成。
5.3 磁盘调度算法
注意,这一块还需要理解书上的磁盘结构图。
磁盘调度算法 | 特点 |
---|---|
FCFS(先来先服务) | |
SSTF(最短时间查找) | 可能导致饥饿 |
Elevator(电梯) | 沿磁头方向选最近请求,如没有请求则掉头 |
SCAN(扫描) | 要达到一端再改方向(要注意到底向哪一端才是向着柱面号大的方向走) |
C-SCAN(循环扫描) | 最后柱面和第一柱面相连 |
5.4 其他
-
提前读、延迟写 -> 重要的提升磁盘I/O的方法
-
SPOOLing应用:独占 -> 共享
书本原话:SPOOLing技术是用一类物理设备模拟另一类物理设备的技术,是使独占变共享设备的一种技术
6. 文件管理
5、6章有较多知识点未展示。感兴趣的可以参考本文前言第三点。
6.1 FCB(文本控制块)
是否联想到了PCB?
定义:操作系统为每个文件建立的唯一数据结构。
6.2 目录
定义:目录是一类特殊文件,一个目录作为一个文件,也对应一个FCB
目录文件永远不会空,至少包含当前目录目录项".“和父目录目录项”…"
i-node索引节点
设置 i − n o d e i-node i−node节点的好处:减少启动磁盘的次数,加快按名存取速度。