一文搞定考研408的《操作系统》
Posted ZSYL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一文搞定考研408的《操作系统》相关的知识,希望对你有一定的参考价值。
学习笔记
零碎
- CPU利用率:指CPU“忙碌时间占总时间的比例”
- 系统吞吐量:单位时间完成的作业的数量
- 系统吞吐量 = 总共完成了多少道作业 / 总共花的时间
- 周转时间 = 作业完成时间 - 作业提交时间
- 平均周转时间:各作业周转时间之和 / 作业数
- 带权周转时间:作业周转时间 / 作业实际运行时间
- 平均带权周转时间:各作业的带权周转时间之和 / 作业数
- 等待时间 = 周转时间 - 运行时间
- 响应比 = 等待时间+要求服务时间 / 要求服务时间
进程同步
进程互斥的软件实现方法
- 单标志法: 两个进程在访问完临界区后会把使用临界区的权限转交给另一个进程,也就是每个进程的临界区权限只能被另一个进程赋予
- 双标志后检查法: 先上锁后检查,产生‘饥饿’现象。
- Peterson 算法:孔融让梨,主动让对方使用临界区(在进入区:主动争取-主动谦让-检查对方是否想进-己方是否谦让),主要问题 不遵循‘让权等待’,会发生忙等
进程互斥的硬件实现方法
- 中断屏蔽方法:关中断-临界区-开中断(只适用于操作系统内核进程,单处理机)
- TestAndSet指令:old记录是否已被上锁,再将lock设为true,检查临界区是否已被上锁。修改lock的值,返回原来的值,
优点: 实现简单,适用于多处理机环境
缺点:不满足‘让权等待’ - Swap指令:用硬件实现,执行过程不允许被中断,只能一气呵成,交换两个变量的值。
信号量机制
1,在双标志先检查法中,进入区的“检查”、上锁,操作无法一气呵成,从而导致两个进程有可能同时进入临界区的问题。
2,所有解决方案都无法实现“让权等待”
- 用户进程可以通过使用操作系统提供的1对原语来对信号量进行操作,从而很方便的实现进程互斥,进程同步
- 信号量其实就是一个变量(可以是一个整数,也可以是更复杂记录型信号量),可以用一个信号量来表示系统的某种资源。
- 原语:是一种特殊的程序段,其执行只能一气呵成,不可被中断。原语是由关中断/开中断指令实现。
- 一对原语:wait(s),signal(s);
整型信号量
用一个整型变量作为信号量,用来表示某种资源的数量
void wait(s){ // wait原语,相当于进入区
while (s <= 0); // 如果资源数不够就一直循环等待
s--; // 如果够就占用一个资源
}
void signal(s) { // 退出区
s++: // 使用完资源后,在退出区释放资源
}
记录型信号量
整型信号量的缺陷是存在忙等。
// 记录型信号量的定义
typedef struct {
int value; // 剩余资源数
struct process *L; // 等待队列
} semaphore;
// 某进程需要使用资源时,通过wait原语申请
void wait (semaphore S) {
s.value--;
if (s.value < 0)
// 如果剩余资源数不够,使用block原语使进程从运行态进入阻塞态,并把挂到信号量s的等待队列(阻塞队列)中
block(s.L);
}
// 使用完资源后,通过signal原语释放
void signal (semaphore s) {
s.value++;
if (s.value <= 0)
// 释放资源后如果还有别的进程在等待这种资源,则使用wakeup原语唤醒等待队列
wakeup(s.L);
}
信号量机制实现进程互斥
1,分析并发进程的关键活动,划定临界区
2,设置互斥信号量mutex,初值为1
3,在临界区前执行P(mutex)
4,在临界区后执行V(mutex)
访问不同的临界资源需要设置不同的互斥信号量,PV操作必须成对出现。
缺少P:就不能保证临界资源的互斥访问
缺少V:会导致资源永不释放 ,等待进程永不会唤醒。
信号量机制实现进程同步
进程同步:要让各并发进程按要求有序推进
由于异步性,因此进程的推进次序不确定的。进程同步:让本来异步并发的进程互相配合,有序推进。
用信号量实现进程同步:
1,分析在什么地方实现“同步问题”,即保证一前一后的执行。
2,设置同步信号量S,初始为0
3,在前操作之后执行V(s)
4,在后操作之前执行P(s)
信号量机制实现前驱关系
每一对前驱关系都是一个进程同步问题
1,要为每一对前驱关系设置一个同步变量
P1() {
...
s1
V(a);
V(b);
}
p2() {
p(a);
s2
V(c);
V(d);
}
互斥pv是在一个进程里面成对显示,同步是分别在两个进程中成对出现
实现互斥的操作一定要在实现同步之后,避免造成死锁。
在生产者消费者问题中,如果缓冲区大小为1,那么有可能不设置互斥信号量就可以实现互斥访问缓冲区的功能。
管程
引入管程的目的就是更方便的实现进程互斥和同步
管程类似于面向对象的封装
- 需要在管程中定义共享数据(缓冲区)
- 需要在管程中定义访问这些共享数据的入口–其实就是一些函数,定义一个函数用于将产品放入缓冲区,再取出
- 只有通过特定的函数才能访问共享数据
- 有很多入口,每次只开放其中一个入口,这种互斥特性是由编译器负责实现的
- 在管程中设置条件变量及等待/唤醒操作以解决同步问题。可以让一个进程或线程在条件变量上等待;可以通过唤醒操作将等待在条件变量的进程或线程唤醒
static class monitor {
private Item buffer[] = new Item[N];
private int count = 0;
public synchronized void insert(Item item) {
......
}
}
死锁、饥饿、死循环
死锁:各进程互相等待对方手里的资源,导致各进程都阻塞,无法向前推进。
饥饿:由于长期得不到想要的资源,某进程无法向前推进的现象。如:短作业优先。
死循环:某进程执行过程一直跳不出某个循环。
死锁的四个必要条件:
- 互斥条件:只有对必须互斥使用的资源的争夺才会导致死锁(如哲学家的筷子,打印机设备) 像内存。扬声器可以同时让多个进程使用资源是不会导致死锁的(因为进程不会阻塞等待这种资源)
- 不剥夺条件:进程所获得的资源在未使用完之前,不能由其他进程强行夺走,只能主动释放。
- 请求和保持条件:进程已经保持了至少一个资源,但请求新的资源,而该资源被其他进程占用,此时请求进程被阻塞,但对自己资源不释放
- 循环等待条件:存在一种进程资源的循环等待链,链中的每一个进程已获得的资源同时被下一个进程所请求。
发生死锁一定循环等待,但循环等待未必死锁。如果每类资源只有一个,那循环等待就是死锁的必要充分条件。
处理死锁&安全序列
安全序列:如果系统按照这种序列分配资源,每个进程顺利完成。只要能找出一个安全序列,系统就是安全状态。安全状有多种。
死锁检测法
依次消除与不阻塞进程相连的边,直到无边可消。
处理
用死锁检测法化简资源分配图后,还连着边的就是死锁进程
- 资源剥夺法
挂起(暂时放到外存上)某些进程,并抢占资源,并分配给其他进程,防止挂起的进程长时间得不到资源而饥饿 - 撤销进程法
撤销部分全部的死锁进程,代价大 - 进程回退法
让一个或多个死锁进程回退到足以避免死锁的地步
存储器
内存
内存是用于存放数据的硬件。程序执行前需要放到内存中才能被CPU执行。
-
给内存单元编地址
-
内存中有许多小房间即存储单元
-
如果计算机按字节编址,则每个存储单元大小为1字节,即1B,即8个二进制位
-
如果字长为16位的计算机,按字编址,则每个存储单元大小为1字长,即16位2字节。
常用数量单位:
一台手机/电脑有4G内存:4*2^30个字节。如果是按字节编址的话,也就是4 * 2 ^ 30的小房间。这么多小房间,需要2 ^ 32个地址才能一一标识,所以地址需要用32个二进制位表示。 -
相对地址:逻辑地址,绝对地址又称物理地址
-
编译:由编译程序将用户源代码编译成若干模块(编译就是把高级语言翻译成机器语言)
-
链接:由链接程序将编译后的形成的一组目标模块,以及所需的库函数,链接在一起,形成一个完整的装入模块
-
装入(装载):由装入程序将装入模块装入内存运行
装入的三种方式
- 静态重定位:装入地址进行重定位,将逻辑地址变换为物理地址(地址变换在装入时一次完成的)
- 特点:一个作业装入内存中,必须分配其要求的全部内存空间,如果没有足够的内存,就不能装入该作业。
- 动态重定位:并不会立即把逻辑地址转换物理地址,而是地址推迟到程序真正要执行时才进行。需要一个重定位寄存器:存放装入模块的起始位置:允许程序在内存中发生移动
- 交换技术:内存空间紧张时,系统将内存中某些进程暂时换出外存,把外存已具备的进程换入内存(进程在内存与磁盘空间动态调度)
- 磁盘空间分为文件区,对换区,主要追求存储空间的利用率,因此对文件区的空间管理存在对换区。
连续分配管理方式
- 单一连续分配
内存分为系统区和用户区。系统区位于内存的低地址,用户区存放用户的数据,内存中只能有一道用户程序,独占整个用户区。
优点:实现简单,无外部碎片,缺点:只能单用户,单任务。 - 固定分区
为了能多道程序运行,将用户空间划分若干固定大小的分区。
建立数据结构:分区说明表,实现各个分区的分配与回收。每个表项包括对应分区的大小、起始地址、状态,产生碎片。 - 动态分区
可变分区分配,根据进程大小动态建立分区,空闲分区表,空闲分区链
动态分区分配没有内部碎片,但是有外部碎片
内部碎片:分配给进程的某些区域,有些部分没有用上
外部碎片:内存中的某些区域太小难以利用 - 紧凑(拼凑Compaction)解决外部碎片
动态分区分配算法
首次适应算法
每次都从低地址开始查找,找到一个能满足大小的空闲分区。
实现:空闲分区以地址递增的次序排列,每次顺序查找。
空闲分区表,空闲分区链
最佳适应算法
动态分区是连续的分配方式,为各进程分配的空间是连续的一整片区。优先使用小空间,给大进程留下足够空间。
实现:空闲分区递增链接
最坏适应算法
解决最佳适应算法的问题,留下太多难以利用的碎片,可以优先使用最大的连续空闲区,这样分配后的剩余空闲区不会太小。
实现:按照容量递减次序链接
邻近适应算法
首次适应算法每次从链头开始查找,低地址出现很多小空闲分区,每次查找都从上次查找结束位置开始检索,就能解决上次问题。
实现:空闲分区按地址递增(排成循环链表)
分页存储管理
思想:把内存分为一个个相等的小分区,再按照分区把进程拆分一个个小部分
每一个分区成为:页框,内存块,物理块,每一个页框都有一个编号,从0开始
重定位寄存器:装入起始位置
起始地址+目标内存单元相对于起始位置的偏移量
例如:
逻辑地址为80的内存单元:
应该在1号页,该页的起始地址是450,逻辑地址80的相对于起始位置,偏移量是30: 450+30 = 480
1,算出逻辑地址的页号
2, 页号在内存中的起始地址
3,逻辑地址的偏移量
4,物理地址=页面地址+页内偏移量
页号= 逻辑地址/页面长度
页内偏移量=逻辑地址 % 页面长度
假如
用32位二进制位表示逻辑地址,页面大小为2的10次方=1024B=1KB
0号页的逻辑地址空间应该是0~1023,二进制
00000000000 0000000~000000000 1111111111
1号页的逻辑地址空间应该是1024~2047,二进制
00000000001 0000000~000000001 1111111111
页内偏移量 或称 页内地址
页号
K表示页内偏移量表示大小是 2的K次方分内存单元
M位表示页号,有2^M个页面
页表
1个进程对应一张页表
进程的每一页对应一个页表项
每个页表项有 页号 和 块号 组成
页表项按顺序连续的存放内存中
起始地址为X:
M号页对应的页表项一定是存放在内存地址为 X+3*M
3:页表项的大小
如果进程有n个页面,则该进程会占 3*n个字节
分页存储的基本概念
如何实现基本地址转换
逻辑地址结构
页表
基本地址变换
进程切换相关的内核程序负责恢复进程运行环境
程序计数器PC:指向下一条指令的逻辑地址A
页表寄存器(PTR):页表起始地址F+页表长度M
进程未执行时,页面的起始和页表长度 放在进程控制块(PCB)中,当进程被调度时,操作系统内核会把他们放到页表寄存器中。
注意:页面大小是2的整数幂
设页面大小为 L,逻辑地址A 到物理地址 E 的变换过程如下:
①计算页号P和页内偏移量W(P =A/L, W = A%L)
②比较页号和页表长度M,若 P >= M,则产生越界中断,否则继续执行。(页号从0开始,而页表长度至少是1, P=M也会越界异常)
③页表中页号P对应的页表项地址 = 页表的起始地址F+页号P*页表项长度,取出该页表项内容b,即内存块号。
注意:(页表长度指的是每个页表项占多大的存储空间;页面大小指一个页面占多的存储空间)
假设页面大小 L = 1KB,最重要访问的内存块号 b=2,页内偏移量 W=1023 ,则逻辑地址 E=b*L + w
例如:
页面大小L为 1K 字节,页号2对应的内存块号 b = 8,将逻辑地址A=2500转换为物理地址E。等价描述系统按字节寻址,在逻辑地址结构中,页内偏移量占10位,页号为2对应的内存号为8
①计算页号。页内偏移量
P=A/L = 2500/1024 = 2
W = A%L = 2500 % 1024 = 452
②根据题中条件,页号2没有越界。内存号8
③物理地址是:E = b*L + W = 8644
页式管理中地址是一维的
快表
局部性原理
快表
两级页表
两级页表的原理与地址结构
如何实现地址转换
注意细节
分段管理存储的方式
段表
寻址过程
分段与分页的对比
虚拟内存
传统存储管理方式的缺点
局部性原理
虚拟内存的定义
虚拟内存的特征
如何实现虚拟内存技术
页表机制
缺页中断机制
请求换页步骤
页面置换算法
-
最佳置换算法
-
先进先出置换算法(FIFO)
-
最近最久未使用的置换算法(LRU)
-
时钟置换算法
-
总结
页面分配策略
分配策略
何时调入页面
何处调入页面
抖动
工作集
文件系统
组织形式:
向上提供的功能
文件如何存放在外存
逻辑结构
无结构文件
有结构文件
顺序文件
索引文件
索引顺序文件
多级索引顺序文件
文件目录
目录结构
树形结构不利于实现文件共享
无环图目录结构
FCB改进
文件物理结构
文件分配方式
连续分配
连续分配的文件在顺序读写时速度最快
链接分配
文件拓展方便
显式链接
索引分配
索引表的逻辑块号可以隐藏,知道起始位置,对与第几块,直接就计算出来
支持随机访问
-
多级索引
-
混合索引
-
访问次数
- 总结
总结
文件存储空间管理
存储空间的划分与初始化
存储空间管理
空闲表法
空闲链表法
-
空闲盘块链
-
空闲盘区链
位示图法
如何分配和回收
成组链接法
- 如何分配
文件操作
创建
删除
打开文件
系统的打开文件表
读文件
文件共享
基于索引结点的共享方式(硬链接)
符号链接(软链接)
文件保护
口令保护
加密保护
访问控制
文件系统的层次结构
磁盘的结构
磁道磁盘扇区
磁盘的物理地址
磁盘分类
活动头磁盘,固定头磁盘
磁盘调度算法
一次读写所用时间
(王道408考研操作系统)第二章进程管理-第三节8:经典同步问题之吸烟者问题
(王道408考研操作系统)第二章进程管理-第三节11:哲学家进餐问题
(王道408考研操作系统)第二章进程管理-第三节3:实现进程互斥的硬件方法
(王道408考研数据结构)第二章线性表-第三节2:双链表的定义及其操作(插入和删除)