EuDs

EuDs

EuDs's Blog
twitter
github

操作系统复习笔记

期末复习#

第三章 进程#

  • 操作系统进行任务调度和资源分配的基本单位
  • 进程包括:
    1. 程序代码
    • 文本段
    1. 程序计数器和处理器寄存器
    • 函数参数
    • 返回地址
    • 局部变量
    1. 数据段
    • 全局变量
    • 动态分配的内存
  • 进程状态
    • 五态模型
      • 新建
      • 就绪:等待分配给处理器
      • 等待:等待某个事件发生
      • 运行
      • 终止
  • 进程控制块(PCB)
    • 包含信息有:
      • 进程编号
      • 进程状态
      • 程序计数器
        • 下条指令的地址
      • CPU 寄存器
      • CPU 调度信息
      • 内存管理信息
      • 计费信息
      • I/O 状态信息

进程调度#

  • 调度队列

    1. 作业队列
    • 系统中所有进程的集合
    • 当进程 / 作业进入系统时,它们被放入作业队列
    1. 就绪队列
    • 所有驻留在 “(主)内存” 中的进程集合,准备并 “等待” 执行
    1. 设备队列
    • 等待 I/O 设备的进程集合
  • 调度器

    1. 长期调度器或作业调度器
    • 作业队列 -> 就绪队列
    • 在时间共享系统如 UNIX 和 Windows 中可能不存在
      • 它们将每个新进程放入内存以供短期调度器使用

    1. 短期调度器或 CPU 调度器:进程调度
    • 选择下一个应执行的进程并分配 CPU

    • 由于其执行频繁,因此每次选择不能耗时太长,否则就会产生开销

    1. 中期调度器或交换
    • 交换出:将进程从内存移除到磁盘,减少多道程序的程度
    • 交换入:将进程引入内存
  • 上下文切换

    • CPU 切换到另一个进程

对进程的操作#

  1. fork()
    • 新进程由原进程的地址空间的副本组成
    • fork () 的返回代码对于子进程为零
    • 子进程会复制父进程的地址空间和资源,但并不会复制父进程的线程

进程间通信#

  • 共享内存
  • 消息传递

名词解释:#

  • 多道程序:是指始终有一些进程在运行,以最大化 CPU 利用率
  • 时间共享:是指在进程之间频繁切换 CPU,以便用户可以与每个进程交互

第四章 线程#

  • 进程 vs 线程
    • 线程是 CPU 的分布单位
    • 进程是资源的分布单位
    • 线程是进程中的执行单元
      • 一个进程可以包含多个线程,它们共享相同的地址空间和系统资源,如打开的文件、信号。
      • 每个线程有自己的栈空间和执行上下文,但它们在同一个进程内共享代码段、数据段和堆等资源。
  • 多线程编程的好处
    1. 响应性
    2. 资源共享
    3. 经济性
    4. 多处理器架构的利用

多线程模型#

  • 两种线程

    • 用户线程
      • 由用户级线程库提供
    • 内核线程
      • 由操作系统直接提供和管理
  • 内核线程与用户线程之间的关系

    1. 多对一模型
    2. 一对一模型
    3. 多对多模型
    4. 二级模型
      • 主题是多对多模型
      • 一个用户线程(重要任务)可以绑定到一个内核线程
  • UNIX 系统中的 fork () 的两个版本

    1. 复制所有线程
      • 如果在 fork 后没有调用 exec (),则复制所有线程
    2. 仅复制调用 fork () 系统调用的线程
      • 如果在 fork 后立即调用 exec (),则仅复制调用线程

第五章 CPU 调度#

基本概念#

  • CPU 调度决策可能在进程:
    1. 从运行状态切换到等待状态
      • I/O 请求的结果
      • 等待一个子进程终止的调用(例如:wait (NULL);)
    2. 从运行状态切换到就绪状态
      • 当发生中断时
    3. 从等待状态切换到就绪状态
      • I/O 完成
    4. 终止
  • 非剥夺式
    • 一旦 CPU 分配给一个进程,该进程保持 CPU 直到释放 CPU
    • 调度只可能发生在情况 1 和 4。
    • 简单,硬件要求低
  • 剥夺式

调度标准#

  1. CPU 利用率
  2. CPU 吞吐量
    • 每时间单位完成执行的进程数量。
  3. 进程周转时间
    • 从提交进程的时间到完成的时间,包括
      • 等待进入内存
      • 在就绪队列中等待
      • 在 CPU 上执行
      • 进行 I/O
  4. 进程等待时间
    • 进程在就绪队列中等待的时间。
  5. 进程响应时间
    • 从提交请求到产生第一个响应 / 结果的时间

调度算法#

  1. 先来先服务(FCFS)
    • 非剥夺式
    • 护航效应
  2. 最短作业优先(SJF)
    • 最小平均等待时间
    • 种类
      1. 抢占式 SJF 允许抢占当前正在执行的进程
      2. 非抢占式
    • 比较适用于长程调度
  3. 优先级调度
    • 问题:饥饿
    • 解决:老化 – 随着时间的推移提高进程的优先级
  4. 时间片轮转(RR)
    • 专为时间共享系统设计
    • 抢占式
    • 时间量子
      • 需要保证 80% 的 CPU 突发 < 时间量子
    • 响应时间 = 2*(n-1)*q
  5. 多级队列算法
  6. 多级反馈队列算法
    • 最通用的调度算法

多处理器调度#

  • 同质 vs. 异质 CPU
    • 同质:各处理器都一样
  • 多处理器调度的方法
    • 非对称多处理
      • 只有一个处理器(主服务器)拥有所有调度决策,I/O 处理
    • 对称多处理
      • 每个处理器自我调度

第六章 进程同步#

  • 竞争条件
    • 多个进程同时访问和操作共享数据的情况。
    • 共享数据的最终值取决于哪个进程最后完成。

临界区问题#

  • 临界区

    • 每个进程都有一个代码段,称为临界区,在其中访问共享数据
    • 有几个共享变量就有几个临界区
  • 临界区问题解决的标准

    1. 互斥
    2. 进展
    3. 有限等待
  • 彼得森解决方案

    • 举手 + 令牌
  • 硬件基础解决方案

    • 关中断
      • 多处理机不适合
    • 原子操作

信号量#

  • 信号量 S – 整数变量

    • 可以通过非负值初始化
    • 只能通过两个不可分割(原子)操作访问:P () 和 V ()
  • P (): 等待 () 操作

    wait (S) { 
      while (S.value <= 0) ; 	// no-op
        S.value--;
    }
    
  • V () 信号 () 操作

    signal(S){
      S.value++;
    }
    
  • 主要问题:忙等待(自旋锁)

    • 优点
      1. 当进程必须等待锁时,不需要上下文切换
      2. 如果锁预计会被短时间持有,自旋锁是有用的
    • 缺点
      1. 浪费 CPU 周期,其他进程可以有效利用
    • 解决:修改 wait () 和 signal () 的定义 适用于多处理器系统
      • Wait (): 进程可以阻塞自己而不是忙等待
      • Signal (): 将阻塞进程从等待状态更改为就绪状态
  • 实现

    1. 在单处理器环境中
    • 禁用中断
    1. 在多处理器环境中
    • 可以应用临界区

第七章 死锁#

  • 必要条件
    1. 互斥
    2. 保持并等待
    3. 不可抢占
    4. 循环等待

处理死锁的方法#

  1. 预防

    • 提供一套确保至少一个必要条件无法成立的方法
    • 针对条件 2:全有或全无;没有资源时才去申请
    • 针对条件 3:谦让;抢夺
    • 针对条件 4:顺序执行
    • 缺点:设备利用率低,降低系统吞吐量。
  2. 避免

    • 使用附加信息,决定当前请求是否可以满足或必须延迟
    • 方法:
      1. 资源分配图
        • 有环:处于不安全状态;可能处于死锁状态
      2. 银行家算法
  3. 检测与恢复

    • 方法:
      • 等待图
        • 不适用于每种资源类型有多个实例的资源分配系统
      • 银行家算法
    • 何时以及多频繁调用检测算法,取决于:
      • 死锁发生的可能性有多高?
      • 需要回滚的进程有多少?
  4. 无视

第八章#

  • 地址可以表示为

    1. 符号地址
    2. 可重定位地址
    3. 绝对地址
  • 地址绑定

    • 转换:
      • 符号地址 -> 可重定位地址:编译器
      • 可重定位地址 -> 绝对地址:链接编辑器或加载器
    • 发生的时期
      1. 编译时
        • 如果在编译时已知内存位置,则可以生成绝对代码
        • 如果在编译时未知内存位置,则必须生成可重定位代码
      2. 装载时(+ 链接时)
        • 如果在装载时已知内存位置,则可以在此时生成绝对代码
      3. 执行时
        • 如果在编译时和装载时未知内存位置,则绑定延迟到运行时
        • 必须在运行时生成绝对代码

逻辑地址与物理地址空间#

  • 逻辑地址 :CPU

    • 也称为虚拟地址
    • 重定位地址和逻辑地址没有直接关系
  • 物理地址 :内存单元

  • 逻辑(虚拟)地址和物理地址在执行时地址绑定方案中有所不同

    • 可重定位代码由 CPU 查看
    • 绝对代码由内存单元查看
  • 内存管理单元(MMU)

    • 硬件设备,将虚拟地址映射到运行时的物理地址
  • 动态加载

    • 不需要将进程的整个程序和数据加载到物理内存中,直到被调用
    • 好处:
      1. 更好的内存空间利用
      2. 操作系统不需要特殊支持
  • 动态链接

    • 链接推迟到执行时
    • 需要操作系统的帮助

连续内存分配#

  1. 固定大小连续分区
    • 优点
      • 实现简单
      • 开销小
    • 缺点
      • 内部碎片
        • 分配的内存可能大于请求的内存
      • 固定数量的进程
  2. 动态连续分区(可变分区)
    • 孔 – 可用内存块
    • 分配算法
      1. 首次适应:
        • 从头开始,或者从当前位置开始
      2. 最佳适应
        • 需要搜索整个列表,除非列表按大小排序
        • 产生可能被浪费的最小剩余孔
      3. 最差适应
        • 需要搜索整个列表,除非列表按大小排序
        • 小进程多的效果好
    • 问题:
      • 外部碎片
  • 碎片解决方案

    1. 压缩
      • 减少外部碎片
      • 随机调动内存内容,将所有空闲内存放在一个大块中
      • 在执行时进行,只在动态重定位时可能
      • 可能在移动进程和孔时代价高
    2. 分页
    3. 分段
  • 连续内存分配的缺点

    • 主内存中的碎片
    • 磁盘上的压缩是不可能的

分页#

  • 帧:将物理内存划分为固定大小的块

  • 页:将逻辑内存划分为固定大小的块

    • 页大小等于帧大小
    • 查找 n 个空闲帧以加载大小为 n 页的程序
  • 将逻辑地址转换为物理地址
    如果地址空间为 2^m,页大小为 2^n

    • CPU 生成的每个逻辑地址被划分为:
      1. 页号(p: 页号)
        • 用作页表的索引
        • 页表中包含每一页在物理内存的基地址(f: 块号)
        • p = 地址 / 2^n 等于地址的 m-n 位
      2. 页偏移(d: 偏移)
        • 与基地址(f: 块号)结合以定义发送到内存单元的物理内存地址
        • d = 地址 %2n 等于地址的 n 位
    • 物理地址
      1. 帧号(f: 帧号、块号)
      2. 页偏移 (d: 页偏移、块偏移)
  • 页大小的选择

    • 越大:
      • 磁盘 I/O 更高效
      • 页表大小越小
    • 越小:
      • 内部碎片越小
  • 帧表

    • 每个物理页帧有一个条目
      表示
      • 帧是空闲的还是分配给哪个进程
  • 页表

    • 每个进程必须维护一份页表的副本
    • 计算
      • 如果页表条目长度为 4 字节
        • 可以指向 2^32 个物理页帧中的一个(1 比特 = 8 字节)
        • 如果帧大小(= 页大小)为 4KB,系统可以寻址 2^44 字节(2^32×2^12=16TB)的物理内存
      • 对于 32 位 CPU
        • 页大小:4k (=2^12)
        • 表大小:2^32/2^12=1M
        • 每个条目的大小:4 字节
        • 页表的大小为:4 MB
    • 位置
      1. 直接存放在寄存器中:
        • 高效且昂贵
        • 当页表合理小的时候可以
      2. 存放在主内存中,然后用页表基址寄存器(PTBR)存放其位置
        • 进程切换时,加载页表只需要改变 PTBR
        • 每次数据 / 指令访问需要两次内存访问
          • 一次用于页表
          • 一次用于数据 / 指令
      3. 转换后备缓冲区(TLB)也称为关联存储器
        • 并行查找
        • 仅包含少量页表条目

页表结构#

  • 问题:页表可能过大
  • 解决方案:将页表划分为更小的部分
    1. 分层分页
    2. 哈希页表
    3. 反向页表
  1. 分层分页
    • 缺陷:
    1. 需遍历,进程太多
    2. 可能有共享,而进程号只能填一个
    3. 不适用于 64 位
    • 好:
      1. 需要的空间小
  2. 哈希页表
    • 哈希表 -> 在链表中遍历匹配
  3. 反向页表
  • 系统中只有一份页表
  • 每个真实页(或物理帧)内存有一个条目
  • 缺点:
    • 增加了在发生页引用时搜索表所需的时间
    • 导致内存共享困难

分段#

  • 用户对程序的视图:程序是多个段的集合,段是逻辑单元,例如:
    • 主程序
      • 过程,函数,方法,对象
      • 局部变量,全局变量
      • 公共块
      • 符号表
      • 数组

第九章 虚拟内存#

  • 整个程序不需要在物理内存中。这样的好处有:

    • 程序的大小不再受内存限制
    • 更多程序可以同时运行
    • 加载或交换每个用户程序到内存所需的 I/O 更少,因此程序开始运行得更快
  • 虚拟内存管理

    • 用于描述一种技术的术语,使计算机似乎拥有比实际更多的内存
  • 虚拟内存可以通过以下方式实现:

    • 按需分页
    • 按需分段

按需分页#

  • 思想:仅在需要时将页面带入内存

    • 类似于带交换的分页系统
  • 硬件

    • 页表。需要加一位有效–无效位
      • v -》 页是合法的并在内存中
    • 次级存储
      • 高速磁盘,交换空间
      • 存放那些不在内存中的页面
  • 页错误

    • 访问标记为无效的页面会导致页错误陷阱
    • 处理
      1. 操作系统查看另一个表(PCB)以决定:
        • 无效引用 -> 中止
        • 仅不在内存中(继续到 2)
      2. 获取空帧
      3. 将所需页面交换到帧中
      4. 修改页表,设置有效位 = v
      5. 重新启动导致页错误的指令
    • 特殊:
      1. 一条指令可产生多个缺页中断
      2. 指令复执
      3. 在指令执行时中断。
    • 对比普通中断:
      • 一条指令在执行完后,检查是否有中断请求
        • 有:执行中断
        • 无:执行下一条指令

页面替换#

替换算法

  1. FIFO 页面替换

    • 贝拉迪异常:更多帧 -> 更多页面错误
  2. 最优页面替换(OPT)

    • 替换最后使用的页或后面最长时间用不到的页
  3. 最近最少使用(LRU)算法

    • 思想:最近的过去作为对未来的近似
    • 实现:
    • 计数器
  4. LRU 近似算法

    1. 附加引用位算法
    2. 第二次机会(时钟)
    3. 增强的第二次机会算法
  5. 基于计数的页面替换

    • 最少使用
    • 最多使用
  6. 页面缓冲算法

    • 页面替换算法的辅助过程

帧的分配#

  • 两种主要的分配方案

    1. 固定分配
      • 平均分配
      • 比例分配
    2. 优先级分配
      • 使用优先级而不是大小的比例分配方案
  • 全局 vs. 本地分配

    1. 本地替换
      • 允许进程仅从其自己分配的帧集中选择。
      • 不能增加分配的帧数
      • 不受外部情况影响
    2. 全局替换
      • 允许进程从所有帧的集合中选择替换帧,即使该帧当前分配给其他进程
      • 可以增加分配的帧数
      • 不能控制其页面错误率。
    • 一般来说,全局替换更好。

抖动#

  • 如果一个进程花费更多时间在分页而不是执行上,则称其为抖动
  • 方法
    1. 使用本地替换算法
    2. 工作集策略
      • 计算系统中每个进程的工作集大小
    3. 页面错误频率(PFF)方案
      • 如果实际速率太低,从进程中移除一个帧
      • 如果实际速率太高,分配另一个帧给进程
      • 如果没有空帧,挂起它

其他考虑#

  • 页面大小的选择要考虑到:
    1. 内部碎片
    2. 页表的大小
    3. I/O 开销(寻道时间、延迟时间、传输时间)
    4. 局部性
    5. 页面错误率
      • 顺序访问:页面大小越大,则缺页中断率越小
      • 随机访问:页面大小越大,则可能会导致更多的分页操作,因为可以保留在内存中的页面更少,每个页面错误传输的数据更多。
  • 安装更快的硬盘,或多个控制器与多个硬盘
    • 因为磁盘瓶颈被更快的响应和更高的吞吐量消除,CPU 将更快地获取更多数据

第十章 文件系统接口#

  • 文件
    • 文件是记录在次级存储上的相关信息的命名集合
    • 六个基本操作
      1. 创建
      2. 读 / 写 / 查找
      3. 删除
      4. 截断:擦除文件的内容,但保留其属性,除了长度
    • 辅助操作
      • 打开 (F):
        1. 在磁盘上搜索目录结构以查找条目 F
        2. 将目录条目复制到打开文件表中
        3. 分配文件描述符
      • 关闭 (F):
        1. 将打开文件表中的目录条目复制到磁盘上的目录结构中
        2. 释放文件描述符

访问方法#

  • 文件中的信息可以通过
    1. 顺序访问
    2. 直接访问
    3. 其他访问
      • 涉及为文件构建索引

目录结构#

  • 符号表

    • 目录可以视为一个符号表,将文件名转换为其目录条目
  • 标准

    1. 效率
    2. 命名
    3. 分组
  • 方案

    1. 单级目录
    2. 二级目录
      • 优点
        • 高效搜索
      • 缺点
        • 无分组能力
        • 难以在不同用户之间共享文件
    3. 树形结构目录
      • 优点
        • 高效搜索
        • 分组能力
      • 缺点
        • 难以在不同用户之间共享文件
    4. 非循环图目录
      • 树形结构目录 + 共享子目录或文件
      • 创建一个新的目录条目称为链接以实现共享
      • 难点在于在添加新链接时避免循环
    5. 一般图目录
      • 向现有树形结构目录添加链接
      • 非循环图目录更好
  • 硬链接

    • ln /usr/local/python3 python
    • 目录中仅存储指向文件数据的指针
    • 允许一个文件被多个目录引用.
    • 无法用来链接目录,也不能跨文件系统
    • 通过ls -i查看是否为硬链接
  • 软链接

    • “快捷方式”
    • 软链接也是一个文件
    • ln -s ../p24 p24
    • 目录从 “树” 变为了 “图”,还是有环图
  • ACL: 访问控制列表

    • 每个文件或目录都有一个 ACL

文件系统实现#

  • 文件系统分为多个层次
    1. 应用程序
    2. 逻辑文件系统
      • FCB: 文件控制块
    3. 文件组织模块
    4. 基本文件系统
    5. I/O 控制
    6. 设备

分配方法#

  • 分配方法指的是如何为文件分配磁盘块

  • 连续分配

    • 每个文件占用磁盘上的一组连续块
    • 支持顺序访问和直接访问(随机访问)
    • 问题:
      1. 外部碎片
      2. 文件无法增长
  • 链接分配

    • 每个文件是磁盘块的链表:块可以散布在磁盘的任何地方
    • 优点
      1. 容易实现
      2. 无外碎片
      3. 文件增长方便
    • 缺点:
      1. 无法随机访问
      2. 可靠性差
      3. 慢(链表保存在磁盘上,因此需要多次查询)
    • 改进: 文件分配表(FAT)
      • 将链表信息放在一个单独的 FAT 表中,而不是各个数据块中,并进行备份
  • 索引分配

    • 将所有指针集中到一个位置:索引块

    • 解决大文件的问题

      1. 链接方案
        • 链接索引表的块
      2. 多级索引
      3. 组合方案
        • 一部分是直接指针,一部分是多重间接块
    • 标准

      1. 存储利用效率
      2. 数据块访问时间
      • 连续分配:适合已知大小的文件
      • 链接分配:适合存储利用
      • 索引分配:访问时间取决于索引结构、文件大小、块位置

空闲空间管理#

  • 空闲空间列表的实现
    1. 位向量
      • 优点
        • 实现简单
        • 找到第一个空闲块效率高
      • 缺点
        • 位图需要额外空间
        • 除非整个向量保存在主内存中,否则效率低
    2. 链表(空闲列表)
      • 优点
        • 没有空间浪费
      • 缺点
        • 遍历列表时效率低
    3. 分组
    • 第一个空闲块存储 n 个空闲块的地址
    • 更容易找到大量空闲块

大容量存储系统#

  • 磁盘结构

    • 磁盘盘片
    • 轨道
    • 扇区
      • 每个轨道被细分为几个扇区
    • 柱面
      • 是在一个臂位置上的轨道集合
  • CLV vs. CAV

    1. CLV : 恒定线速度
      • CD-ROM, DVD-ROM
      • 最外层区域的轨道包含更多扇区
    2. CAV : 恒定角速度
      • 磁盘
      • 从内轨到外轨的比特密度降低,以保持数据速率恒定

磁盘调度#

  • 访问时间
    1. 寻道时间是磁盘臂移动到包含所需扇区的柱面的时间
      • 寻道时间  寻道距离
    2. 旋转延迟
      • 等待磁盘旋转到所需扇区到磁盘头
  • 磁盘带宽
    • 传输的字节总数 / 从第一次请求服务到最后一次传输完成的总时间
  1. FCFS 调度
  2. SSTF:最短寻道时间优先(SSTF)
    • 最短寻道时间优先
    • 问题:
      • 往返跑 --- 距离很短,但速度不一定很快
      • 可能导致某些请求的饥饿
  3. 扫描
  • 有时称为电梯算法
  1. C-SCAN(循环扫描)
  • 磁头从磁盘的一端移动到另一端,服务请求
  • 当它到达另一端时,立即返回到磁盘的开头,而不在返回途中服务任何请求
  • 回途不载客
  1. LOOK / C-LOOK
  • 类似于 SCAN/C-SCAN

  • 臂仅移动到每个方向的最后请求,然后立即反向,而不首先到达磁盘的末端。

  • 选择
    性能取决于请求的数量和类型

    • SCAN 和 C-SCAN 在对磁盘施加重负载的系统中表现更好
    • SSTF 或 LOOK 都是合理的默认算法选择

磁盘管理#

  • 磁盘格式化
    • 低级格式化(物理格式化)
      • 将磁盘划分为磁盘控制器可以读取和写入的扇区
    • 逻辑格式化
      • 创建文件系统
      • 为文件系统构建元数据结构

RAID 结构#

  • 便宜磁盘冗余阵列(过去)

  • 独立磁盘冗余阵列(现在)

    • 用于其更高的可靠性和更高的数据传输率(性能)
  • 级别

    1. RAID 0
      • 数据条带化的磁盘阵列,但没有冗余
    2. RAID 1
      • 磁盘镜像
    3. RAID 2
      • 位级条带化或字节级条带化
      • 内存风格的错误校正码(ECC)
    4. RAID 3
      • 位交错奇偶校验
    5. RAID 4
      • 块交错奇偶校验组织
    6. RAID 5
      • 块交错分布式奇偶校验

常用单词#

  • simultaneously : 同时地
  • idle : 空闲,懒
  • reside : 位于,居住
  • uni-processor : 单处理器
  • interleave: 交织
  • allocation : 分配
  • dashed line : 虚线
  • minuscule : 微小的
  • concrete : 具体的
  • mandatory: 强制的
  • mediate : 调解
  • strip : 脱掉;条
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。