操作系统A期末复习

建议配合电脑食用

目录

第一章 操作系统概述

计算机软件定义及分类

计算机基本组成结构:网络设备 + 中断结构 +总线结构

中断结构:计算机系统由中断来驱动

总线结构(Bus):数据 / 地址 / 控制 / 扩展 / 局部

I / O 端口寻址和访问控制:统一 / 独立、轮询 / 中断 / DMA / 通道

操作系统

概念:① 管理 硬件/系统资源;② 提供基础;③ 中介作用;

作用:① API;② 资源利用;③ 运行环境;

分类:批处理 / 分时 / 实时 / 分布式 / 网络 / 嵌入式

特征与功能

结构:简单 / 分层式 / 微内核 / 虚拟机

常见操作系统:UNIX / Windows / Linux

第二章 进程管理

进程

概念

进程实体

特性:① 动态性;② 并发性;③ 独立性;④ 异步性;⑤ 结构特性

进程状态和转换

进程控制块和进程队列:① 链接方式;② 索引方式

进程控制:内核与原语

线程 (Thread)

概念

同步与互斥

概念

信号量:用于实现临界区的互斥访问

整型信号量:S <= 0,进程忙等

记录型信号量:① S.value > 0,可用资源量;② S.value < 0,绝对值 → 等待进程数

临界区代码保护原则:① 互斥进入;② 有空让进;③ 有限等待

经典同步问题

生产者 - 消费者:三个信号量

读者与写者问题

进程通信

定义

通信方式:基于文件 IO 的思想 → ① 消息传递;② 共享存储器;③ 管道通信

进程调度

CPU 调度程序

调度准则

调度策略:非抢占式:FCFS、SJF、HRN;抢占式:SRTF、优先级、RR、MQ

死锁

预防死锁:破坏死锁产生的 4 个条件

避免死锁:找出安全序列

死锁的检测与解除:发现问题再解决

第三章 内存管理

存储器的层次结构

概念

程序的装入:① 绝对装入;② 静态重定位;③ 动态重定位

程序的链接:① 静态链接;② 装入时动态链接;③ 运行时动态链接

重定位 / 地址映射

单一连续内存管理

固定分区分配

可变分区分配

可重定位分区分配

分页存储管理

页面与页表

管理

两级和多级页表

快表

分段式存储管理

段页式管理

覆盖与交换

虚拟存储器

请求分页存储管理方式

页面分配策略

第四章 设备管理

I / O 硬件

设备控制器

I / O 软件

I / O 设备的使用方式

设备驱动程序

缓冲管理

① 单缓冲:每当用户进程发出一个 I / O 请求时,OS 便在内核区域为之分配一个缓冲区,大小为一个块;

② 双缓冲:单缓冲的改进,可以实现用户数据区—缓冲区之间交换数据和缓冲区—外设之间交换数据并行,分配两个大小为一个块的缓冲区;

③ 循环缓冲:多个大小相等的缓冲区链接成一个循环队列,in 指针指向下一个可以冲入数据的空缓冲区,out 指针,指向下一个可以取出数据的满缓冲区。

存储设备

常见的存储外设:磁带、磁盘、光盘

磁盘调度

RAM 盘

磁盘阵列

文件管理

文件

文件的访问:① 顺序访问;② 随机访问;③ 索引访问

顺序文件

索引文件

多级索引顺序文件

直接文件和哈希文件

文件保护:① 口令保护;② 加密保护;③ 访问控制

口令保护

加密保护

访问控制

文件目录

文件系统的实现

连续分配

链接分配

索引分配

文件系统的结构

存储空间管理

空闲表法:适用于连续分配方式

空闲链表法

位示图法

文件系统实例

FAT

Linux 文件系统


第一章 操作系统概述

计算机软件定义及分类

  • 计算机系统 = ((软件 = 计算机系统中的程序及相应的文档)+ (硬件));
  • 可分为:系统软件(譬如操作系统)-支撑软件-应用软件。
  • 额外知识:API、系统调用、内核
  • API:作为函数的定义,规定该函数的功能的应用编程接口;
  • 系统调用:操作系统提供给用户程序获得内核服务的接口,可以看成是特殊的公共子程序;
  • 内核:操作系统的核心,提供最基本的功能,负责多种硬件管理,譬如文件、内存、进程、网络等等,为用户层程序提供系统调用接口,不提供库函数;
  • 一对多:一个API需要一或多个系统调用来完成特定的功能;
  • 相同:程序员调用API(函数)与系统调用共同完成函数功能;
  • 不同:系统调用是通过中断间接向内核发请求(计算机系统由中断来驱动),而API跟内核无直接关系。

计算机基本组成结构:网络设备 + 中断结构 +总线结构

  • 冯·诺依曼
  • 存储程序思想:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制下一步一步进行处理;
  • 计算机的五大部件:运算器、控制器、存储器、输入设备、输出设备。

中断结构:计算机系统由中断来驱动

总线结构(Bus):数据 / 地址 / 控制 / 扩展 / 局部

  • 定义:是一组信号线集合,用作计算机各部件之间传输数据和命令的公共通道。
  • 分类:
  • ① 数据总线(Data Bus):CPU ← (数据) → RAM;

左走处理,右走储存;

  • ② 地址总线(Address Bus):指定 RAM 中储存的 数据 的 地址;
  • ③ 控制总线(Control Bus):微处理控制单元 → (信号) → 周边设备;
  • ④ 扩展总线(Expansion Bus):用于 电脑 与 扩展槽 的连接;
  • ⑤ 局部总线(Local Bus):实现高速数据传输的高性能总线。
  • 额外知识:主存 RAM
  • RAM:随机存取存储器,也叫主存;除刷新外可随时读写,断电不保存
  • 技术规范:机械结构规范 / 功能规范 / 电气规范;
  • 总线结构:单总线 / 双总线 / 三总线。

I / O 端口寻址和访问控制:统一 / 独立、轮询 / 中断 / DMA / 通道

  • I / O 端口编址方式:统一编址:存储器 共用同一片寻址地址空间;② 独立编址:I / O 单独编址;
  • I / O 控制方式:① 轮询;② 中断;③ DMA;④ 通道;
  • 读操作:① ~ ②:I / O 设备 → CPU → 内存;③ ~ ④:I / O 设备 → 内存。

操作系统

概念:① 管理 硬件/系统资源;② 提供基础;③ 中介作用;

  • 关系:计算机硬件-操作系统-应用软件;

往左走是管理,右走提供基础,作为计算机硬件和用户之间的中介。

作用:① API;② 资源利用;③ 运行环境;

  • OS 是 Operating systems 即操作系统的缩写负责用户与硬件之间的所有的通信,如果没有就需要显性告诉硬件做什么。
  • 使系统编程接口 API 更简单:为上层环境提供系统调用和各种库函数,对物理裸机进行抽象;
  • 额外知识:裸机、库函数、libc
  • 裸机:没有配置操作系统和其他软件的电力计算机;
  • 库函数:由 libc 提供而非内核提供;
  • libc:Linux 的 c 语言 函数库。
  • 使系统资源利用更充分:使进程的并发和共享更易实现;
  • 资源共享两种方法:
  1. 时分:针对使用时间,多个用户分时使用资源;
  2. 空分:针对存储资源,将存储资源的空间以分割的方式共同占用。
  • 使程序运行环境更友好:用命令解释程序与用户进行交互,通过对进程的控制与调度来运行用户的程序(内核负责)。

分类:批处理 / 分时 / 实时 / 分布式 / 网络 / 嵌入式

  • 按用户界面分:命令行界面 / 图形用户界面 操作系统;
  • 按用户数分:单用户 / 多用户 操作系统;
  • 按任务数:单任务 / 多任务 操作系统;
  • 按系统功能:
  • 批处理系统:计算机自动地、有序地完成用户作业;
  • a. 单道批:每次只调度一个作业进入内存运行;
  • b. 多道批:增加了多种硬件管理,提高 CPU、内存和 I / O 设备的利用率,增加系统吞吐量;
  • 分时操作系统CPU 的单位时间 → 若干时间片 → 分配给多个用户;
  • 实时操作系统(RTOS):能在规定的时间之内进行快速响应,具有高可靠性,是一种专用的操作系统;
  • 分布式操作系统:物理上分散独立,逻辑上集中,互相协作完成计算或处理;
  • ⑤ 网络操作系统:网络上的计算机共享网络资源,主要运行在各种服务器上;
  • ⑥ 嵌入式操作系统:高度集成的,专用的操作系统。

特征与功能

  • 操作系统特征:
  • 并发性:改善利用率、提高系统吞吐量;
  • 共享性:资源共用,不被某个程序独占;
  • 虚拟性:物理实体 → 若干个逻辑上的对应物;
  • 异步性:程序的执行具有独立性,执行发展是不可预测的。
  • 功能:① 处理机(进程)管理;② 存储器(内存)管理;③ 设备管理;④ 文件管理;⑤ 用户接口。

结构:简单 / 分层式 / 微内核 / 虚拟机

  • ① 简单结构 MS - DOS:汇编编写,没有拆分模块;
  • ② 分层式结构:硬件裸机基础上一层一层向外扩充软件,最底层:硬件 → ……→ 最高层:用户界面,每一层仅使用更低一层的功能和服务
  • ③ 微内核结构:尽可能将代码移出核心,将系统服务与系统的最基本操作分离开;
  • ④ 虚拟机结构:运行在裸机上的核心软件(虚拟机监控软件/某一种操作系统)为基础,向上提供虚拟机的功能。每台虚拟机上都可以运行一台裸机所能够运行的任何类型的操作系统。

常见操作系统:UNIX / Windows / Linux

  • UNIX:在由汇编语言改为 C 语言编写后具有了可移植性,分为 内核 和 外壳(Shell) 两部分;

第二章 进程管理

假设总共有 A 、B 两个程序需要执行,可分为单道 / 多道程序进行执行,前者是按顺序依次执行,时间叠加,后者是多道程序交替执行,时间轴重合;

  • 询问譬如 CPU 的利用率时:
  • 单道程序:CPU 利用率 = [ A(占用 CPU 时间) + B(占用 CPU 时间)] ÷ [ A(执行时间) + B(执行时间)]
  • 多道程序:CPU 利用率 = [ A(占用 CPU 时间) + B(占用 CPU 时间)] ÷ 执行所用时间

进程

概念

  • 进程:具有一定功能的程序在一个数据集合上的运行过程,是系统进行资源分配和调度管理的一个可并发执行的基本单位;

进程实体

  • 组成:程序控制块(PCB) + 程序段 + 数据段;
  • 进程与进程实体:
  • ① 进程实体是静态概念;
  • 进程是进程实体的运行过程。

特性:① 动态性;② 并发性;③ 独立性;④ 异步性;⑤ 结构特性

  • 进程与程序:
  • a. 进程是动态的,程序是静态的;
  • b. 一对多:程序 → n 进程,进程 → 程序。

进程状态和转换

  • 进程状态:① 就绪(Ready)状态;② 执行(Running)状态;③ 阻塞(Blocked)状态;

动态性:进程总是在这三个基础状态间切换

  • 对于 阻塞 来说:① 阻塞 无法到 执行;② 就绪 无法到 阻塞;

也就是说,只有 就绪 状态的进程才能被执行,只有 执行 状态的进程才可能因为 等待资源、事件 而回退到 阻塞 状态

  • 单 CPU 的计算机同一时刻只有一个进程处于运行态。

进程控制块和进程队列:① 链接方式;② 索引方式

  • PCB块:进程控制块,用来记录进程信息的数据结构;

一个进程只有一个 PCB,作为进程存在与否的唯一标记,创建与撤销针对的是PCB。

  • 两种组织方式:
  • 两者的区别在于,链接方式的指针直接指向 PCB 块;索引方式的指针指向索引表,索引表再指向 PCB 块,只有一个进程的情况下不用建立索引表;

比如 单 CPU 的计算机中,索引方式里的执行指针直接指向当时运行的唯一进程;

  • ① 链接方式:按进程状态将 PCB 分成多个队列,持有指向各个队列的指针;

即,执行指针、就绪队列指针、阻塞队列指针;

  • ② 索引方式:根据进程状态不同,建立几张索引表,持有指向各个索引表的指针;

即,执行指针、就绪表指针、阻塞表指针。

进程控制:内核与原语

  • 内核通过执行各种原语操作来实现操作;
  • 原语是操作系统中调用核心层子程序的指令,具有原子性,不可中断

原语进行的操作:① 更新 PCB 中的信息;② 将 PCB 插入到合适的队列;③ 分配 / 回收资源;

  • 原语的分类:
  • ① 进程创建原语:创建 / 初始化 PCB,分配空间及安排对应的状态队列;
  • ② 进程撤销原语:由于正常终止 / 异常终止 / 外界干预而引起撤销;
  • ③ 阻塞原语:使进程状态由 执行 → 阻塞;
  • ④ 唤醒原语:使进程状态由 阻塞 → 就绪。
  • 额外知识:多程序并发执行、创建进程函数 fork()
  • 进程并发执行的两个基本属性:

① 资源的拥有者:给每个进程分配一虚拟地址空间,保存进程映像,控制资源,有状态、优先级、调度;

② 调度单位:进程是一个执行轨迹。

  • 从程序 1 切换至 程序 2 ,OS 需要做的是:

① PC 中数据修改为程序 2 对应开始的指令地址;

② PCB 块记录转移时程序 1 中存储器的数据以及结束程序 2 后从哪儿返回程序 1 的地址。

  • 创建进程函数 fork() 的返回值:

父进程中:fork 返回新创建子程序的进程 ID;

子进程中:fork 返回 0;

出错:fork 返回一个负值。

线程 (Thread)

概念

  • 类比线程与进程:
  • 多对一:一个线程对应一个进程,一个进程对应多个线程;
  • ② 是谁的基本单位:进程 → 系统 的 调度管理 + 资源分配,线程 → 进程 的 调度 + 分派;
  • ③ 地址空间:资源的拥有者会给每个进程分配一虚拟地址空间,一个进程的多个线程必须共享地址空间;
  • ④ 状态(<进程> → <线程>):a. 执行 → 运行;b. 阻塞 → 阻塞;c. 就绪 → 就绪;d. 终止 → 终止;
  • ⑤ 管理(<进程> → <线程>):进程管理 由 内核 采用 原语 进行操作。a. 进程创建 → 线程创建;b. 进程撤销 → 线程终止;c. 进程唤醒 → 线程等待;d. 进程阻塞 → 线程让权;
  • 额外知识:用户级线程与核心级线程的区别、线程池 

  • ① 系统调用:OS 内核级可知,用户级不可知;
  • ② 进程的创建等操作:OS 内核级需要 OS 支持,用户级在语言(Java)层就可处理;
  • ③ CPU调度的基本单位:有 OS 内核支持的系统内,以 线程 为基本单位;只有用户级的系统内,以 进程 为基本单位;
  • ④ 栈:OS 内核级的线程需要在一个核心栈里跑,用户级的线程需要在一个用户栈里跑,二者合在一起称为一套栈。

  • 线程池

       处理线程多并发问题:用一个数组保存线程,使用条件变量让空闲的线程休眠,若加入了新的任务,则唤醒其中一个线程去执行这个任务

同步与互斥

概念

  • 同步与互斥概念对比:
  • ① 相同:并发进程间;
  • ② 不同:a. 同步 → 共享资源,互斥 → 独占资源;b. 同步 → 为协调资源占用而相互等待、相互交换信息,互斥 → 互相竞争使用;
  • 同步已经实现了互斥,同步是一种更为复杂的互斥;
  • 互斥是一种特殊的同步。
  • 访问无序:互斥无法限制访问者对资源的访问顺序;
  • 临界资源:一次只能允许一个进程使用,具有唯一性和排它性;
  • 临界区:每个进程中访问或者使用临界资源的那段代码程序。

       线程需要进入临界区使用临界资源,但临界资源一次只能允许一个进程使用,进程处于等待资源状态即从执行态变为阻塞态,等到前一个线程使用完,后一个才能进入临界区。

信号量:用于实现临界区的互斥访问

P 操作 → 使进程阻塞;V 操作 → 唤醒进程 / 使进程就绪;临界区操作 → 介于 P、V 之间

  • 一般情况下操作的作用:
  • P 操作:① 进入临界区;② 资源数目 - 1;
  • V 操作:① 离开临界区;② 资源数目 + 1;

整型信号量:S <= 0,进程忙等

  • 定义:用于表示资源数目的整型量 S ;
  • 访问方式:① 初始化;② 原子操作 P:wait(s);③ 原子操作 V:signal(s);
  • P 操作:
wait(s):  while  s <= 0  do no-op; //  “while … do no-op”,no-op 为空指令,指当满足 … 这个条件时什么都不干,即忙等

            s := s-1; // “:=” 即 “定义为”,右边新定义的符号表达左边的值
  • V 操作:
signal(s):  s := s+1;

记录型信号量:① S.value > 0,可用资源量;② S.value < 0,绝对值 → 等待进程数

多个等待同一信号量的进程排成一个队列,由信号量的指针项指示该队列的队首;

  • 组成:整型变量 + 指向 PCB 的指针;
  • 含义:① 大于 0 :表示当前可用资源数量;② 小于 0 :绝对值表示等待进程个数;
  • P 操作:
void  P(S){

       S.value --;

       if(S.value < 0){

          将这个进程加到 S.list 队列;

          block();}

}
  • V 操作:
void V(S){
     S.value ++;
     if(S.value <= 0){
       从 S.list 队列中将进程 P 移走;
       wakeup(P);}
}

临界区代码保护原则:① 互斥进入;② 有空让进;③ 有限等待

  • 互斥进入:保证这是临界区 → 一次只能有一个进程进入;
  • ② 有空让进:若干进程要求进入空闲临界区时,应尽快使一进程进入临界区;
  • ③ 有限等待:从进程发出进入请求到允许进入,不能无限等待。

经典同步问题

  • 每类共享资源设置一个信号量 s,其初值为 1,表示该临界资源未被占用;
  • 做题模式:① 分析 同步、互斥关系;② 确定 P、V 大致顺序;③ 设置信号量;

生产者 - 消费者:三个信号量

  • 确定 P、V 大致顺序:先生产再消费;
  • 设定信号量:
  • ① 从操作性质上看:互斥操作 → 互斥型号量 mutex:用于互斥访问缓冲区,初始化值为 1 (判断缓冲区的临界资源是否被占用);
  • ② 从功能角度上看:
  • a. 生产者:产出数据 → 询问缓冲区是否有空位 → 资源信号量 emptyBuffer:初始化值为 n (缓冲区大小);
  • b. 消费者:取出数据 → 询问缓冲区是否有数据 → 资源信号量 fullBuffer:初始化值为 0 (表明缓冲区一开始为空)
// 定义所使用的信号量

#define N 100
semaphore mutex = 1;            // 互斥信号量,用于临界区的互斥访问
semaphore emptyBuffer = N;      // 资源信号量,用于生产者询问缓冲区是否有空位
semaphore fullBuffer = 0;       // 资源信号量,用于消费者询问缓冲区是否有数据

// 生产者

void producer()
{
    while(TRUE)
    {
        P(emptyBuffer);         // 记录临界区中的空位数目 -1
        P(mutex);               // 进入临界区
        将生成的数据放到缓冲区中;
        V(mutex);               // 离开临界区
        V(fullBuffer);          // 记录临界区中的数据数目 +1
    }
}

// 消费者

void consumer()
{
    while(TRUE)
    {
        P(fullBuffer);           // 记录临界区中的数据数目 -1
        P(mutex);                // 进入临界区
        从缓冲区里读取数据;
        V(mutex);                // 离开临界区
        V(emptyBuffer);          // 记录临界区中的空位数目 +1
    }
}

读者与写者问题

  • 限制:① 允许多个读者同时读;② 读者与写者互斥;③ 写者与写者互斥;
// 定义所使用的信号量

semaphore rw = 1;        // 实现对文件的互斥访问
int count = 0;
semaphore mutex = 1;     // 实现对count变量的互斥访问

// 写者

while(1){
   P(rw);                // 写之前“加锁”
   写文件;
   V(rw);                // 写之后“解锁”
}

// 读者

while(1){
   P(mutex);             // 各读进程互斥访问count
   if(count == 0)        // 第一个读进程负责“加锁”
      P(rw);
   count++;              // 访问文件的读者数+1
   V(mutex);
   读文件;
   P(mutex);             // 各读进程互斥访问count
   count--;              // 访问文件的读者数-1
   if(count == 0)        // 最后一个读进程负责“解锁”
      V(rw);
   V(mutex);
}
  • ① 写写互斥 / 读写互斥 → 设置 rw 为互斥信号量,初值为 1 → 文件当前空闲可用;
  • ② 读读允许 + 读写互斥 →
  • a. 设置 count 整型变量,初值为 0 → 记录当前访问文件的读者数目;
  • b. 需要根据读者数目,判断何时加锁 / 解锁,写者是否可进 → 存在临界区代码 → 对 count 需要有互斥操作 → 设置 mutex 为互斥信号量,初值为 1 → 读者是否可以进入 count 对应的临界区。

进程通信

定义

  • 进程通信:指进程之间可以直接以较高的速率传输较多的数据和信息的信息交换方式;
  • 进程通信与线程通信:
  • ① 进程通信 → a. 无法在用户空间实现;b. 通过 Linux 内核通信;
  • ② 线程通信 → a. 可以在用户空间实现;b. 可以通过全局变量通信。

通信方式:基于文件 IO 的思想 → ① 消息传递;② 共享存储器;③ 管道通信

  • 消息传递:通过通信类系统调用进行通讯;

发送原语:send 接收者进程名字,发送区首地址

接收原语:receive 发送者进程名字,接收区首地址

  • a. 一对一通信:明确指定接收者与发送者;

两个进程名字合起来就是一条用于信息传递的信道。

  • b. 客户 / 服务器系统中的通信(C / S 模式):用户访问的数据可能存放在网络的某个服务器;

(1)套接字 / 插口(socket):每个进程一个,通信需要一对;

(2)远程过程调用(RPC):允许程序调用另外机器上的进程;

(3)信箱:由信箱头和包括若干信格的信箱体组成,每个信箱具有自己唯一的标识符,允许向不知名的进程发送消息,大多支持双向通信。

  • 共享存储器:需要交换的信息发送到某一约定的存储区域,可实现 2 个或 2 个以上进程间的通信,可以将内存中的一个区域连入多个进程的虚拟地址空间

使用到的系统调用:创建、附接、断接、状态查询。

  • 管道通信:一种信息流缓冲机构,用于连接发送进程和接收进程;

以先进先出(FIFO)的方式组织数据的传输,通常用于有共同祖先的进程间的信息交换,交换信息量大,但 I / O 操作次数较多。

进程调度

  • 概念:通过某种规则或算法从就绪(等待)进程队列中选出一个进程投入运行。

CPU 调度程序

  • CPU 调度程序:负责在 CPU 上切换进程,决定进程状态的转换;

由排队程序、分配程序、上下文切换程序组成:

① 排队程序:进程由执行 → 阻塞,更新进程描述符并通过指针关联;

② 分配程序:将 CPU 的控制交由下一个被选择的进程;

③ 上下文切换程序:保存从 CPU 移除进程的所有处理器寄存器的内容到进程的 PCB 中。

  • 调度策略:确定进程何时从 CPU 移除并且应当接着将 CPU 分配给某个等待的进程。
  • 调度在四种情况下发生:① 执行 → 阻塞;② 执行 → 就绪;③ 阻塞 → 就绪;④ 执行 → 终止;

就绪 → 执行 就是靠的被调度。

  • 调度策略分为两大类:
  • ① 非抢占式调度策略:进程无法被中止,CPU 将被占用一直到该进程结束或者切换到等待状态才能被释放;
  • 可抢占式调度策略:进程允许中断,被中断的会被移入就绪队列。

调度准则

影响调度算法选择的主要因素:设计目标、公平性、均衡性、综合平衡、基于相对优先级;

调度性能评价:CPU 使用率、吞吐量、周转时间、就绪等待时间、响应时间。

调度策略:非抢占式:FCFS、SJF、HRN;抢占式:SRTF、优先级、RR、MQ

  • 周转时间:从进程到达一直到进程结束所使用的时间;
  • 等待时间:从进程到达一直到进程开始运行所使用的时间;

下面的算法是为了排序,重点是计算时间。

  • 先来先服务调度算法(FCFS):

  • 方法内容:谁先到谁先用 CPU ,一直用到进程结束(非抢占性);

这道题由于数量级差距过大所以省略了到达时间。

  • 短作业优先(SJF):具有最小的平均等待时间

  •  方法内容:谁占用 CPU 时间最短谁先用 CPU ,一直用到进程结束(非抢占性);
  • 最短剩余时间优先调度(SRTF):
  • 方法内容:谁先到谁先用 CPU ,下个进程到时进行对比还需占用 CPU 的时间,更短的上(抢占式);
  • 优先级调度算法:
  • ① 静态优先级:创建进程时就确定下来的优先级,并且保持不变;

抢占式算法可能会产生“饥饿”现象:优先级比较低的进程可能无限期等待 CPU 调用;

  • ② 动态优先级:随着进程的推进优先级会不断变化;
  • 方法内容:就绪队列中谁优先级最高谁先上;
  • 高响应比优先调度算法(HRN):

  •  方法内容:R 大的先上(非抢占式);
  • 时间片轮转算法(RR):适用于分时系统,平均等待时间相当长

时间片大:响应时间太长;时间片小:吞吐量小。

  • 方法内容:CPU 会给出一个时间片交给就绪队列的进程依次使用(抢占式);

比如 A 进程 10 ms,B 进程 5 ms,给出的时间片 4 ms,那么由 A 进程先用,剩余 10 - 6 = 4 ms,CPU 交给下个 B 进程抢占,剩余 5 - 4 = 1 ms,再交给 A 进程抢占 CPU。

  • 多级队列调度算法(MQ):
  • 方法内容:就绪队列划分为多个独立的队列,每个队列有自己的调度策略,队列之间可以按优先级调度,也可以按时间片轮转调度(抢占式)。

死锁

  • 定义:多个进程由于互相等待对方持有的资源而造成谁都无法执行;
  • 4 个必要条件:① 互斥使用;② 不可抢占;③ 请求和保持:进程必须占有资源再去申请;④ 循环等待:在资源分配图中存在一个环路(方向也得成环);
  • 资源分配图:描述系统资源和进程的状态的有向图,二元组 G = (V,E);

V 为顶点:① 资源节点(方框);② 进程节点(圆圈);

E 为有向边:① 进程 → 资源:请求边;② 资源 → 进程:分配边;

  • 若图中存在环路,则可能存在死锁,如果每个资源类中只包含一个资源实例,则见环路必死锁;
  • 死锁处理方法:① 死锁预防;② 死锁避免;③ 死锁检测 + 恢复;④ 死锁忽略。

预防死锁:破坏死锁产生的 4 个条件

  • ① 一次性申请所有需要的资源;② 对资源进行排序,从而按序进行资源申请 → 破坏环路。

避免死锁:找出安全序列

安全序列:系统中的所有进程存在的一个可完成的执行顺序,使系统处于安全状态

  • 资源分配图算法(在每种资源只有一个的时候使用):
  • 具体操作:标出所有资源点和进程点,某进程若会在稍后某些时候请求资源,则在它俩中间画一条虚线的请求边,当将资源分配给它后,转为实线的分配边,此时观察,若出现环,则说明会产生死锁;
  • 注意:这方法目的是搞出来能执行完所有进程的安全序列顺序!!!
  • 银行家算法:

A、B、C 是资源种类,数字是资源个数,P 是进程;

  • 第一列 Allocation:进程现在所占有的资源数目;
  • 第二列 Need:完成进程还所需的资源数目;
  • 第三列 Available:现在空闲的资源个数;
  • Work:可使用的空闲资源个数
  • 具体操作:
  • ① Availabe 就是用来给第一次的 Work 赋值,后头用到的都是 Work;
  • ② Work 和 Need 比较,比后者大,此进程就可以执行;
  • ③ 执行完的进程的 Allocation 加入 Work 里,继续重复比较;
  • ④ 如果找不到 比 Work 小的 Need 了,就说明现在找的安全序列是不安全的;
  • ⑤ 如果一个安全序列都找不到,说明这个系统会发生死锁。

死锁的检测与解除:发现问题再解决

定时检测或者是发现资源利用率低时检测。

第三章 内存管理

存储器的层次结构

概念

  • 存储管理的目的:
  • ① 内存分配 / 定位:为具体的程序和数据等分配存储单元或存储区工作;
  • ② 地址映射:逻辑地址 → 物理地址;
  • ③ 内存保护:按存储权限把合法区与非法区分隔;
  • ④ 内存扩充:在硬件支持下,软硬件相互协作,将内存和外存结合起来统一使用。

名空间 → (编译连接) → 地址空间 → (地址映射) → 存储空间

  • 名空间:标识符、程序符号的集合;
  • 地址空间:程序员访问信息使用的,由编译程序生成的,逻辑 / 相对地址的集合;
  • 存储空间:由装配程序等生成的,物理 / 绝对地址的集合;
  • 逻辑地址(相对地址,虚地址):首地址为 0 ,其余指令中的地址都相对于首地址而编址,不能用逻辑地址在内存中读取信息;
  • 物理地址(绝对地址,实地址):内存中存储单元的地址,可直接寻址;

程序的装入:① 绝对装入;② 静态重定位;③ 动态重定位

  • 重定位:修改程序中的相对地址;
  • ① 编译时,程序只能放在内存固定位置;
  • ② 载入时,程序一旦载入内存就不能动了。
  • 交换(swap):从磁盘中换入内存,当内存中的进程睡眠时,将其换出到磁盘;
  • 地址翻译:每执行一条指令都要从逻辑地址算出物理地址 → 基地址 + 偏移量;
  • 三种装入方式:
  • ① 绝对装入:编译或汇编时 / 程序员直接赋予 → 物理地址;
  • ② 静态重定位装入方式:程序装入时一次性地完成程序中所有地址敏感指令及数据的地址修正且以后不再改变,并且装入后不允许发生内存位置的移动;
  • ③ 动态重定位装入方式:伴随程序的执行逐步完成程序中所有地址敏感指令及数据的地址修正,装入内存后的所有地址仍是逻辑地址。

程序的链接:① 静态链接;② 装入时动态链接;③ 运行时动态链接

  • 装入时动态链接:一边装入一边完成对程序各目标模块的连接,便于修改和更新,实现对目标模块的共享;
  • 运行时动态链接:在执行过程中未被用到的目标模块不会被调入内存和链接到装入模块上,可加快程序的装入过程,节省大量的内存空间。

重定位 / 地址映射

  • 定义:作业地址空间中的逻辑地址 → 内存空间中的物理地址;
  • 静态重定位:程序装入内存时,一次性完成逻辑到物理的地址转换,由软件完成,且以后不再转换;
  • 动态重定位:程序运行过程中,要访问数据时候再进行地址转换,由地址变换机构进行的地址转换,硬件上需要重定位寄存器的支持。
  • 重定位寄存器:存放偏移量的地方;
  • 映像方式:采用页表描述虚、实页面的对应关系,存放逻辑页与物理页帧的对应关系。

每一个进程都拥有一个自己的页表,PCB 表中有指针指向页表。

单一连续内存管理

  • 使用静态分配和静态重定位方式,适用于单用户系统:一段时间内只有一个进程在内存;
  • 存储保护的实现:划分 OS 区与用户区
  • ① 自动地址修改:OS 在低 4 K,访问 + 4 K;OS 在高 4 K,地址为访问的 ÷ 8 取余。

       存储器的地址空间为 12 K,操作系统位于低址端的 4 K 内。给用户一个13 位的地址空间,并对其每个存储器访问自动加上 4 K。

       如果操作系统占用高址端的 4 K,则取每一个存储访问 R ,实际上,其地址为(R mod 8 K);

  • ② 0 页、1 页寻址:对每个用户生成的地址左端拼接上一位 1 来实现 OS 区与用户区;
  • ③ 界限寄存器:划分 OS 区与用户区。

固定分区分配

  • 基本思想:内存划分为若干个连续区域,即分区,其大小可相同可不同,但大小固定不变;每个分区只能存储一个程序,而且程序也仅能在对应分区里运行;
  • 存储分配:有一个空闲区就分给进程。

可变分区分配

  • 基本思想:在作业装入时,动态划分内存分配给作业,在作业释放归还内存后,空间会合并;

空闲的内存大小 > 作业大小 → 按需划分给它;空闲的内存大小 < 作业大小 → 不分,等别人释放以后满足 > 条件再分给它。

注意:假设存在 A、B、C 三个连续内存块,B 被使用,A、C 空闲,能使用的空闲是 A 、C 这两个单独的,而不是 A + C,等 B 释放是和它邻近进行合并,实际上是存在顺序的。

  • 内存管理:设置内存空闲块表 —— 记录了空闲区起始地址和长度;
  • 数据结构:
  • ① 空闲分区链表:空闲块由指针链接起来形成链表;

  •  ② 分区分配表:

  •  分区算法:

② 是需要分割空闲块的,其余都是分配

  • ① 最佳适应法:找大小最接近作业需求的存储区域分配给它;
  • ② 最坏适应法:找最大的空块分割给它;
  • ③ 首次适应法:将分区按地址从高到低搜索,只要找到可以容纳作业的空白块,就分配给它;
  • ④ 循环首次适应法:同理 ③ ,但是是从上次结束的地方开始;
  • 碎片问题:一段时间后,内存中会存在很多很小的空闲块;

可重定位分区分配

  • 引入动态重定位 → 引入紧凑技术;
  • 解决碎片问题 → 紧凑技术:通过在内存移动程序,把所有小的空闲区域合并为大的空闲区域;
  • 连续分配:为用户进程分配的必须是一个连续的内存空间;
  • 非连续分配:为用户进程分配的可以是一些分散的内存空间;
  • 多重分区:将放入内存的程序改为放入其的作业片段;增加重定位寄存器,作业片段之间就不需要连续;
  • 分区的保护:
  • ① 界限寄存器方式:防止地址越界,增加读写保护;
  • ② 保护键方式:给分区分配一个单独的保护键,给进程分配一个相应的保护键;
  • ③ 二者结合。

分页存储管理

页面与页表

  • 页 / 页面:一个进程的逻辑地址空间分成的若干个大小相等的片,大小通常为 512 B ~ 8 KB;
  • 物理块 / 页框:内存空间分成的,与页面相同大小的,若干个存储块;
  • 页内碎片:以块为单位将进程中的若干个页分别装入多个可以不相邻接的物理块中,由于进程的最后一页经常装不满一块而形成了不可利用的碎片,称之为“页内碎片”;
  • 页表:列出作业的逻辑地址与其在主存中的物理地址间的对应关系;
  • 地址结构:

页号 = [逻辑地址 ÷ 页面大小] 取整;

页内地址 = [逻辑地址 ÷ 页面大小] 取余;

位移量 = 页面大小写成 2 的次幂形式,位移量即为其的指数;

物理地址 = 块号 + 页内地址;

逻辑地址 = 页号 + 页内地址;

管理

  • ① 页表:存在内存里,属于进程的现场信息;
  • ② 空块管理:
  • a. 位示图:

横排为页标,纵排为块标排序,列表,如果空闲则对应格标记为 0 ,如果被占用了就标 1;

  • b. 内存页表
  • ③ 内存的分配与回收:

a. 计算一个作业所需要的总块数 N;

b. 查位示图,若有足够的空闲块,则页表长度设为 N;

c. 申请页表区,把页表始址填入 PCB;

d. 一次分配空闲块,把块号和页号填入页表;

e. 修改位示图。

两级和多级页表

  • 多级页表:加了个页目录;
  • 两级页表:

 外层页号 → 【页目录表】 → 页表地址 +(外层页内地址)→ 【页表】 → 块号 +(页位移)→ 【内存块】 → 代码或数据

快表

  • TLB:一组相联快速存储寄存器;

由于程序的地址访问存在空间局部性(程序多体现为循环、顺序结构),导致 TLB 条目数在 64 - 1024 就能起作用。

  • 快表的作用:
  • 访问内存时,先查找快表,能找到所需的页描述子就可快速形成物理地址,找不到再从页表查找,同时把页描述子写入快表;

能找到 → 命中

分段式存储管理

  • 定义:按照程序自身的逻辑关系划分为若干个段,每段从 0 开始编址;
  • 以段为单位分配,每个段在内存中占据连续空间,各段之间可以不相邻;
  • 地址结构:

 段表始址 +(段号)→【段表】→ 基址 +(位移量)→ 【主存】→ 物理地址

  • 段表:

段页式管理

  • 分段和分页的主要区别:
  • ① 分页为系统行为,用户不可见;分段包含一组属于一个逻辑模块的信息,对用户可见;
  • ② 分页的用户进程地址空间是一维的;分段是二维,标记一个地址时,既要段名也要段内地址;
  • ③ 分段比分页更容易实现信息的共享和保护;

纯代码 / 可重入代码(不属于临界资源):不能被修改,但可共享。

  • 段页式管理:对用户来说,按段划分;对系统来说,按页划分每一段。(先分段 → 再分页)
  • 地址结构:

 段表始址 +(段号)→【段表】→ 页表始址 +(段内页号)→【页表】→ 页 +(页内地址)→ 程序

覆盖与交换

用于解决程序大小超过物理内存总和的问题

  • ① 覆盖技术(对用户不透明):按照自身逻辑结构,让那些不可能同时被访问的程序段共享同一个覆盖区;
  • ② 交换技术(动态调度):当内存空间紧张时,可将内存中的某些进程暂时移到外存,把外存中的某些进程换进来,占据前者所占用的区域。

虚拟存储器

  • 传统存储管理具有:
  • ① 一次性:作业需一次性装入内存才能开始运行;
  • ② 驻留性:载入后会一直驻留在内存中,直至运行结束;
  • 局部性原理:
  • ① 时间局部性:程序中的某条指令被执行后不久很有可能再次执行;
  • ② 空间局部性:一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也很有可能被访问。
  • 虚拟存储器:具有请求调入功能和置换功能,从逻辑上把内存和外存有机结合起来,对内存扩充;

CPU 寻址范围 → 最大容量;

实际容量为 min ( 内存外存容量之和,CPU 寻址范围);

  • ① 多次性:允许作业分为多次调入内存;
  • ② 对换性:作业运行过程中,允许被换入、换出;
  • ③ 虚拟性:在逻辑上扩充了内存容量。

请求分页存储管理方式

和分页式的区别是它可以换进换出,页表记录的会多一些字段,譬如:

① 是否在内存的状态位;

② 最近被访问几次或什么时候被访问的访问字段;

③ 页面调入内存后是否被修改过的修改位;

④ 页面在外存存放位置的外存地址。

  • 缺页中断机构:每当要访问的页面不在内存时,就算一次缺页中断,其属于内中断;
  • ① 内存有空闲块,页面可载入进去;
  • ② 内存没有空闲块,根据置换策略,选择某个页面挪去外存,把要访问的页面挪进来;
  • 页面置换算法:画表格,横排访问页面,纵排内存块序号,其对应横排记录载入该内存块的页面,最后一排记录是否缺页
  • 最佳置换算法(OPT):每次换出的页面是 a. 以后永不使用;b. 在最长时间呃逆不再被访问的页面;
  • 先进先出置换算法(FIFO):每次换出的页面是 最早进入内存的页面
  • 最近最久未使用置换算法(LRU):每次换出的页面是 最近最久未使用的页面;

做题的时候可以在边上画个栈,每次来个页面就压入栈,如果同样的页面又被调用,就提到栈顶,否则继续往下压,被换出的页面是在栈底的页面,注意顺序不要乱搞

  • 时钟置换算法 / 最近未用算法(CLOCK / NRU):用到了页表里记录的访问位,要换出页面时候,就按序对访问位进行扫描,换出为 0 的页面,如果第一轮都是 1 ,那么重置为 0 ,再次进行扫描;
  • 改进型的时钟置换算法:同理 ④ ,但是多了个修改位;
  • 换出的页面类型:a. 访问位 0 ,修改位 0;b. 访问位 0,修改位 1;
  • 具体操作:多轮扫描,第一轮先找 a,找不到第二轮找 b,并且把扫描过的访问位全置 0 ;一直重复下去,直到找到;
  • ⑥ 最少使用置换算法(LFU):为各页设置一移位寄存器用于记录被访问频率,换出近期使用次数最少的页面;
  • ⑦ 页面缓冲算法(PBA):利用可变分配和基于先进先出的局部置换策略,规定被换出页面先不做物理移动,根据是否修改分别挂到 a. 空闲页面链表;b. 已修改页面链表的末尾;
  • a 用于物理块分配,b 达到一定长度就写回磁盘。
  • 影响缺页次数的因素:① 分配给进程的物理页面数;② 页面本身的大小;③ 程序的编制方法;④ 页面淘汰算法。

页面分配策略

  • 驻留集:请求分页存储管理中给进程分配的物理块的集合;

在采用虚拟技术的系统中,其大小一般小于进程的总大小

  • ① 大小不变 → 固定分配:为进程分配一组固定数目的物理块,在运行期间不再改变;
  • ② 大小可变 → 可变分配:先分配一定数目的物理块,运行期间可根据情况适当的增加或减少;
  • 局部置换:缺页时只能选进程自己的物理块进行置换;
  • 全局置换:可动用操作系统的空闲物理块,也可换其他进程的物理块到外存;
  • 预调页策略:用于进程的首次调入;
  • 请求调页策略:运行时发现缺页再调入。

做题时候注意,如果它预先调页进去,物理块就不是空的,不一定会发生缺页  ↑

  • 抖动 / 颠簸 现象:刚刚换出的页面马上要换入,刚刚换入的马上要换出;主要原因:进程频繁访问的页面数目高于可用的物理块数;
  • 工作集:在某段时间间隔里,进程实际访问页面的集合。

第四章 设备管理

I / O 硬件

  • I / O 设备:输入数据到计算机或接收输出数据的外部设备;
  • 分类:
  • 按使用特性:① 人机交互类外部设备;② 存储设备;③ 网络通信设备;
  • 按传输速率:① 低速设备;② 中速设备;③ 高速设备;
  • 按信息交换的单位:① 块设备:可寻址;② 字符设备:不可寻址。

设备控制器

  • ① 接受和识别 CPU 发出的命令;
  • ② 向 CPU 报告设备的状态;
  • ③ 数据交换;
  • ④ 地址识别;
  • 一个 I / O 控制器可能对应多个设备。
  • 组成:① CPU 与控制器之间的接口;② I / O 逻辑;③ 控制器与设备之间的接口;
  • 两种寄存器编址方式:① 内存映射 I / O:统一编址,指令通用;② 寄存器独立编址:独立编址,专门指令;
  • I / O 控制方式:
  • ① 程序直接控制方式:计算机每读一个字的数据,都要确认其是否在 I / O 设备的寄存器中;
  • ② 中断驱动方式:允许 I / O 设备打断 CPU 来请求服务,单位为字;
  • ③ DMA 方式:以块为单位,在设备与内存之间直接传输数据,只有在开始或结束的时候需要 CPU 进行干预,剩余都是在 DMA 控制器的控制下完成的;
  • ④ 通道控制方式:DMA 方式的进化,把 CPU 对一个数据块的干预增加至一组。

I / O 软件

  • 系统设备表—SDT:记录了系统中全部设备的情况,每个设备对应一个表目;
  • 设备控制表—DCT:系统为每个设备配置一张DCT,用于记录设备情况;

I / O 设备的使用方式

  • ① 独占式共享使用设备;② 分时式共享使用设备;③ 以 SPOOLing 方式使用外设。
  • SPOOLING:通过软件模拟脱机技术,把独占设备改造为共享设备,也叫虚拟设备。

设备驱动程序

  • 功能:① 控制有关 I / O 设备的各种控制器;② 对各种设备排队、挂起、唤醒等操作进行处理;③ 执行确定的缓冲区策略;④ 进行比寄存器接口级别层次更高的一些特殊处理;
  • 特性:和 I / O 设备的硬件结构密切相关,是 OS 底层中唯一知道各种 I / O 设备的控制器细节及其用途的部分;
  • 接口函数:① 驱动程序初始化函数;② 驱动程序卸载函数;③ 申请设备函数;④ 释放设备函数;

缓冲管理

  • 作用:一般用内存作为缓冲区
  • 缓冲区数据非空时,只能传出不能传入,当缓冲区为空时,只能等充满以后才能传出数据;
  • ① 缓和 CPU 与 I / O 设备之间速度不匹配的矛盾;
  • ② 减少对 CPU 的中断频率,放宽对 CPU 中断相应时间的限制;
  • ③ 解决数据粒度不匹配的问题;
  • ④ 提高 CPU 与 I / O 设备之间的并行性。

① 单缓冲:每当用户进程发出一个 I / O 请求时,OS 便在内核区域为之分配一个缓冲区,大小为一个块;

② 双缓冲:单缓冲的改进,可以实现用户数据区—缓冲区之间交换数据和缓冲区—外设之间交换数据并行,分配两个大小为一个块的缓冲区;

③ 循环缓冲:多个大小相等的缓冲区链接成一个循环队列,in 指针指向下一个可以冲入数据的空缓冲区,out 指针,指向下一个可以取出数据的满缓冲区。

存储设备

常见的存储外设:磁带、磁盘、光盘

  • 磁盘块:用(柱面号,盘面号,扇区号)定位。

磁盘调度

  • 寻找时间 / 寻道时间:启动磁头臂时间 + 移动磁头时间 = 启动磁头臂时间 +(跨越磁道数 × 跨越一个磁道耗时);
  • 延迟时间:两倍转速的倒数;
  • 传输时间:此次读 / 写的字节数 ÷(磁盘转速 × 每个磁道上的字节数)
  • 总的平均存取时间:上面三个加起来。
  • 面向寻道的磁盘调度算法:会给个表格,做题画个按大小排序的磁道号的横轴,按照表格给的从几号开始,下个是谁等信息画箭头,箭头长度为移动距离等比例大小。
  • 先来先服务 FCFS:表格里按顺序画;
  • 最短寻道时间优先 SSTF:寻道时间最短,平均寻道时间不一定最短,按离当前磁道最近的磁道顺序画下去;
  • 电梯调度 SCAN:在当前移动方向上选择与当前磁道距离最近的画;
  • 循环扫描调度算法 C-SCAN:磁头只做单向移动,走完最外的,立即返回最里,按同样的方向,完成扫描;
  • ⑤ FSCAN 算法:SCAN 的简化,分成两个队列,一个是当前请求 I / O 的队列,按 SCAN 做,一个是扫描期间新出现的请求 I / O 队列,放到下次扫描做;
  • 存储出错处理:① 程序性错误;② 瞬时校验错误;③ 永久性校验错误;④ 寻道错误;⑤ 控制器错误。

RAM 盘

  • 将一块内存区域虚拟成磁盘块设备,支持写数据块和读数据块操作;

磁盘阵列

  • ① RAID 0:无容错功能的条带磁盘阵列,用块级条带化分割数据,并行地读 / 写于多个磁盘,无可靠性保障;
  • ② RAID 1:阵列单元为一对互为备份的磁盘,任一盘读取,一个失效可以自动交换到镜像磁盘上;
  • ③ RAID 0 + 1:一组磁盘被条带化分割,然后镜像化;
  • ④ RAID 2:使用位条带化,磁盘中相应位都计算一个海明错误校正码,保存在多个奇偶校验磁盘中的相应位;
  • ⑤ RAID 3:④ 的发展,用异或逻辑运算校验代替海明码,条带宽度为字节;
  • ⑥ RAID 4:块交错奇偶校验结构,块级条带化,在单独磁盘上保存奇偶校验块,失效后可与其他磁盘上保存的对应块一起来恢复;
  • ⑦ RAID 5:与 ⑥ 不同在,奇偶校验和数据一起分布在磁盘上,不用单独一块磁盘;
  • ⑧ RAID 6:和 ⑦ 相比,增加了第二个独立的奇偶校验信息块,即使两个磁盘同时失效也不会影响。

文件管理

文件

  • 定义:一种抽象数据类型,建立字符流到盘块集合的映射关系,对用户来说是最小的数据存储单元,可保存数值、文本或者二进制的机器代码;
  • 存放:OS 以“块”为单位为文件分配存储空间,存放在外存;
  • 分类:
  • 按文件性质与用途:① 系统文件;② 库文件;③ 用户文件;
  • 按操作保护:① 只读文件;② 可读可写文件;③ 可执行文件;
  • 按使用情况:① 临时文件:工作过程中产生的中间文件,过后会删除;② 永久文件;③ 档案文件:软件或系统记录在案的文档资料文件;
  • 按用户观点:① 普通文件;② 目录文件;③ 特殊文件:管理输入输出设备的文件,对其的操作会被 OS 转接指向相应的设备操作;
  • 按存取的物理结构:① 顺序文件:存到连续的物理盘块;② 链接文件:存到不相邻接的物理块,由链接指针组成一个链表管理;③ 索引文件:同 ② ,由索引表项按关键字存取,索引表管理;
  • 按文件中的数据形式:① 源文件:由源程序和数据构成;② 目标文件:源程序编译后形成的 .OBJ 或 .o 文件;③ 执行文件:目标文件与相关库函数或子程序链接后形成的二进制可运行文件。

文件的访问:① 顺序访问;② 随机访问;③ 索引访问

  • 无结构文件 / 流式文件:内部数据就是一系列二进制流或字符流组成;
  • 有结构文件 / 记录式文件:由一组相似的记录组成,每条记录又由若干个数据项组成;

顺序文件

  • 文件中的记录逻辑上按序排列,记录可以是定长或可变长的,物理上可顺序存储或链式存储;

索引文件

  • 使用本身是定长记录顺序文件的索引表查找索引项,但是是可变长记录文件;

多级索引顺序文件

  • 为顺序文件建立多级索引表 → 给索引表再建索引表;

直接文件和哈希文件

  • 直接文件:根据给定的记录键值,可直接获得指定记录的物理地址;
  • 哈希文件:给定的记录键值需要通过哈希函数运算才能得到记录的物理地址;

文件保护:① 口令保护;② 加密保护;③ 访问控制

口令保护

  • 用户请求访问文件时必须提供口令;

加密保护

  • 访问文件时需要提供正确的密码;

访问控制

  • 在 FCB 或索引结点中增加一个访问控制列表,记录各个用户可以对该文件执行哪些操作;

文件目录

文件系统中主要数据结构之一

  • 对目录管理的要求:① 实现“按名存取”;② 提高对目录的检索速度;③ 文件共享;④ 允许文件重名;
  • 文件控制块 FCB / 目录项:包含文件基本信息、存取控制信息、使用信息,是文件存在的标志;
  • 文件目录:所有 FCB 的有序集合;
  • 目录文件:将文件目录以文件的形式保存在外存;
  • ① 单级目录结构:整个系统中只建立一张目录表,每个文件占一个目录项;按名存取,不允许文件重名;
  • ② 两级目录结构:分为主文件目录和用户文件目录;允许不同用户的文件重名;
  • ③ 多级目录结构 / 树形目录结构:各级目录之间以 / 隔开;
  • 绝对路径:从根目录出发的路径;根据它找需要 3 次读磁盘 I / O 操作;
  • ④ 无环图目录结构:③ 基础上增加一些指向同一节点的有向边,可以用不同文件名指向同一个文件;
  • 索引节点(FCB 的改进)瘦身:
  • 每个盘块能存放的 FCB 个数 = 磁盘大小 ÷ FCB 大小;
  • 文件目录需要占用的盘块个数 = 文件目录中的目录项个数 ÷ 每个盘块能存放的 FCB 个数;

文件系统的实现

  • 磁盘块的大小与内存块、页面的大小相同;
  • 磁盘块与内存之间的数据交换以“块”为单位;

连续分配

  • 每个文件在磁盘上占有一组连续的块,可以直接算出逻辑块号对应的物理块号,支持顺序访问和直接 / 随机访问;

链接分配

  • 读入 i 号逻辑块,需要 i + 1 次磁盘 I / O ,只支持顺序访问,不支持随机访问;
  • ① 显式链接:用于链接文件各物理块的指针显式地存放在文件分配表 FAT 中,一张磁盘一张分配表,放入内存中;
  • ② 隐式链接:除文件的最后一个盘块,每个盘块都有指向下一个盘块的指针;

索引分配

  • 文件离散分配在各个磁盘块中,OS 为每个文件建立一张索引表,记录文件各个逻辑块对应的物理块;
  • 存放索引表 → 索引块,存放文件 → 数据块;
  • ① 链接方案:如果索引表过大,一个索引块放不下可以分多个;
  • ② 多层索引:多个索引块依次指向;
  • ③ 混合索引:①②结合;

文件系统的结构

应用软件 → 逻辑文件系统 → 文件组织模块 → 基本文件系统 → I / O 控制 → 磁盘设备

存储空间管理

空闲表法:适用于连续分配方式

  • 分配:与内存管理中的动态分区分配类似,为一个文件分配连续的存储空间,可采用首次适应、最佳适应、最坏适应等算法;
  • 回收:① 回收区的前后无相邻空区;② 前后都是相邻空区;③ 回收区前面是空区;④ 后面是空区;

空闲链表法

  • ① 空闲盘块链:以盘块为单位的空闲链;
  • 分配:按序摘下盘块分配,并修改空闲链的链头指针;
  • 回收:按序挂到链尾,并修改空闲链的链尾指针;
  • ② 空闲盘区链:以盘区为单位的空闲链;
  • 分配:采用首次适应、最佳适应等算法,从链头开始检索,若没有适合的连续空闲块,也可以将不同盘区的盘块同时分配给一个文件;
  • 回收:回收区与空闲盘区相邻,则合并,若没有,则挂到链尾;

位示图法

  • 一般用连续的字来表示,字长为盘块个数,每个二进制位对应一个盘块,0 代表盘块空闲,1 代表盘块已分配

文件系统实例

FAT

  • 采用链表作为文件分配结构;
  • 文件以簇的方式存放,簇里存放了一个文件就不能再存放另外的文件;

Linux 文件系统

  • ext2 系统:使用索引节点记录文件信息;每个文件对应一个索引节点;

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值