操作系统学习笔记(本文为期末复习篇)

一、概论

1.1 发展过程(理解)

  1. 手工操作阶段:人工或脱机I/O方式;
  2. 批处理阶段
    • 单道批处理:内存中仅有一道程序运行。磁带的作业自动逐个进入内存运行。
    • 多道批处理⭐:内存放入多道相互独立的程序,多道程序轮流占有CPU
  3. 分时操作系统⭐:
    • 时间片为单位轮流为各个用户/作业提供服务,时间到了就打断
  4. 实时(及时)操作系统:能够优先响应一些紧急的任务,不用等待时间片排队;
  5. 网络操作系统:把计算机网络中的各台计算机结合起来。
  6. 分布式操作系统:系统中的各计算机相互协同并行完成同一任务。
  7. 嵌入式操作系统:固定在硬件里面的系统。

1.2 基本特性🔥

  1. 🔥并发:指两个或多个事件在同一时间间隔(交替执行)。
    • 并行是同一时刻每个核处理一个任务;
  2. 共享:资源多个并发执行的进程共同使用;
    • 互斥共享:计算机的某个资源在一段时间内只允许一个进程使用,例如摄像头。
    • 同时共享:计算机的某个资源在一段时间内允许多个进程同时使用。
  3. 虚拟:
    • 时分复用技术:(并发性)如CPU分时共享,让多道程序并发执行的方法。
    • 空间复用技术:如虚拟存储器。
  4. 异步:任务的执行以不可预知的速度向前推进。

1.3 主要功能(往后的章节)

  1. 处理机管理(二、三)
    • 进程控制、进程同步、进程通信、作业/进程调度。
  2. 存储器管理功能(四、五)
    • 内存分配和回收、内存保护、地址映射、内存扩充。
  3. 设备管理(六、输入输出)
    • 完成I/O请求,提高CPU和I/O设备利用率。
  4. 文件管理(七、文件,八、磁盘)
    • 文件存储、目录管理、文件读写管理和保护。
  5. 接口管理(九)
    • 提供用户与操作系统之间的交互界面。例如GUI(图形用户界面),命令形式。

二、进程管理

2.1 前趋图

表示进程间的关系,会看会画;

参考链接:如何画前趋图?

2.2 并发

  • 概念🔥:两个或多个事件,同一时间间隔执行,微观上是交替,宏观上是同时进行。

  • 特征(了解):间断性、失去封闭性(共享)、不可再现性;

2.3 进程

定义:是进程实体的运行过程,是系统进行资源分配调度的一个独立单位。

引入进程的目的✅:使程序并发执行,提高资源利用率和系统吞吐量

(1) 进程的状态(三种)
  • 就绪态:具备除CPU外的所有资源,准备好允许的状态,没有空闲CPU;
  • 执行态
    • 已有CPU,正在执行;
  • 阻塞态:进程的执行受到阻塞。
(2) 进程状态转换🔥
  • 创建态 ➡ 就绪态:申请空白PCB,填写并分配资源。

  • 执行态 ➡ 就绪态❗ ;执行态 ➡ 阻塞态❗

    img
(3) 进程的挂起与激活
  • 挂起:将进程暂时从内存中移出,保存到外存中。

    • 可以提高内存的利用率
    • 降低系统的工作负荷
  • 挂起代表静止的,激活(未挂起)代表活动的

    • 则把3个状态细分成5个;
(4) 进程控制块PCB🔥
  • PCB的作用
    • 独立运行基本单位的标志。(程序有了它,变成进程)
    • 能实现间断运行;(进程的特性)
    • 提供进程管理所需的信息
    • 提供进程调度所需的信息
    • 实现与其他进程的同步与通信
  • PCB中的信息🔥
    1. 进程标识符
    2. 处理机状态
    3. 进程调度信息
      • 进程状态
      • 优先级
      • 事件等等
    4. 进程控制信息
      • 程序和数据的地址
      • 同步和通信的机制:信号量、消息队列指针;
  • 组织方式
    • 线性、链性、索引
(5) 进程控制

进程管理的最基本功能;

  • 进程创建
    • 进程有层次结构,有向树;
    • 过程:申请空白PCB,分配资源,初始化PCB,插入就绪队列;
  • 进程终止
  • 进程阻塞与唤醒
    • 阻塞原语Block()。由执行改为阻塞
    • 唤醒Wakeup()。由阻塞改为就绪
  • 进程挂起与激活
    • 挂起Suspend()
    • 激活Active()
(6) 进程通信✅
  • 低级通信:PV操作(为了实现进程同步,需要信号量,也算通信)
  • 高级通信✅:
    • 共享存储器(数据结构、存储区)

    • 管道通信(共享文件)

    • 消息传递

      • 直接通信:send()、receive()
      • 间接通信:也是上面的原语,通过信箱(私用、公用、共享)
    • 客户-服务器(套接字socket,远程过程调用,远程方法调用)

2.4 进程同步🔥

进程的同步 临界资源(要掌握)临界区(要掌握)较为重要

(1) 基本概念
  • 目的:进程间有效共享与合作,具有可再现性

  • 互斥关系与同步关系

    • (互斥)互斥使用临界资源。
    • (同步)进程间合作。
  • 临界资源🔥

    • 定义:某些资源一次只能一个进程使用;(互斥资源、共享变量)
    • 进程间要采用互斥的方式,对这种资源的共享
  • 同步机制准则🤏(进临界区)

    1. 空闲让进
    2. 忙则等待
    3. 有限等待:不能死等;
    4. 让权等待:不能进入临界区,则释放CPU;
(2) 进程同步机制✅(4个)
  1. 软件同步~:编程方法解决;
  2. 硬件同步~:特殊硬件指令;
  3. 管程~;
  4. 信号量机制🔥🔥
    • 定义🤏:
      • 进入关键代码,进程必须获取一个信号量,否则不能运行;
      • 执行关键代码片段必须释放信号量;
      • 信号量为+,则空闲,为-,则忙碌;
    • 信号量类型:整形、记录型、AND型、信号量集
    • 整形信号量S:
      • 两个不可分割的原子操作,P(S)/wait(s)、V(S)/signal(s)
      • P(S): while s<=0; s:=s-1;
      • V(S): s:=s+1;
    • 记录型S:
      • 结构体:S.value和S.L阻塞队列
    • 应用
      1. 实现进程互斥🔥:例如生产者消费者问题;
        • 互斥信号量初值=1;
        • 临界区之前,执行P操作;
        • 临界区之后,执行V操作;
      2. 实现前趋关系
      3. 实现进程同步
(3) 生产者-消费者问题🔥
  • 注意点:

    • 同步关系:为空时,消费者不能消费;为满时,生产者不能生产;
    • 互斥访问缓冲区一个线程在消费/生产时,其余线程不能消费/生产;
  • PV操作🔥🔥,伪代码实现:

    semaphore mutex = 1;//互斥信号量
    semaphore empty = n;//同步信号量,空闲缓冲区数量
    semaphore full = 0;//同步信号量,产品(非空闲)数量
    /*注:P V成对出现,P是消耗,占用 V是增加,释放*/
    void producer(){
        while(1){//一直循环
            生产一个产品;
            P(empty);//消耗空闲区
            P(mutex);
            产品放入缓冲区;
            V(mutex);
            V(full);//增加产品
        }
    }
    void comsumer(){
        while(1){//一直循环
    		P(full);//消耗产品
            P(mutex);
            从缓冲区取出产品;
            V(mutex);
            V(empty);//增加空闲区
            消费者 消费产品;
        }
    }
    
  • 临界区✅:count--,进程中涉及临界资源的代码片段

  • 进入区:检查是否可以进入临界区的代码;

  • 退出区:临界区标志为未被访问;

(4) 哲学家就餐问题✅(死锁)
  • 逻辑

    • 哲学家饿了先拿起左手的筷子
    • 再拿起右手的筷子
    • 如果筷子被人使用了,那就等别人用完
    • 吃完后,依次把筷子放回原位
  • 使用信号量避免死锁

  • 信号量的伪代码✅实现:

    /*注:(i+1)%5 是右边*/
    semaphore chopstick[5] = {1,1,1,1,1};//互斥信号量初始化
    Philosopher i:
    	do {
           P(chopStick[i]);  //拿起左边筷子
           P(chopStick[(i + 1) % 5]); //拿起右边筷子//吃一段时间V(chopStick[i]); //还回左边筷子
           V(chopStick[(i + 1) % 5]); //还回右边筷子//思考} while (true) 
    
    
(5) 死锁与饥饿
  • 死锁:两个或多个进程,无限期等待一个事件发生;
  • 饥饿🤏:无限期阻塞,进程可能永远无法从等待的队列中移出;

2.5 线程

  • 引入目的:减少时空开销、更好的并发性、更好支持多处理机(多核)系统;

  • 进程与线程的区别✅:

    1. 资源的基本单位:
      • 进程是分配资源的基本单位,多个线程共享隶属进程的资源;
    2. 调度的基本单位:
      • 线程是分配处理机(或调度)的基本单位;
    3. 并发性:
      • 进程之间可并发,在一个进程中,线程也可并发;
    4. 独立性:线程间~比进程间低;
    5. 系统开销(同进程内,线程切换);
    6. 支持多处理机系统;

三、处理机调度与死锁

⼏种调度⽅式 进程调度算法 死锁定义 为什么会产⽣死锁

死锁的必要条件(4种)🔥 预防死锁方法

3.1 调度概述

  • 调度的层次(根据调度的距离)

    1. 高级调度(作业调度)
      • 外存➡内存
      • 多道批处理系统;
      • 为他们创建进程,分配资源,插入就绪队列;
    2. 中级调度(内存调度)
      • 内存➡外存;外存➡内存
      • 暂不运行的,外存等待;要运行的进内存;
    3. 低级调度(进程调度)
      • 就绪队列中,哪个进程可以获得处理机
      • 多道批处理、分时、实时OS
  • 进程调度过程(任务)

    1. 保存处理机现场信息
    2. 按某种算法选进程
    3. 把处理机分配给该进程
  • 进程调度的方式

    • 非抢占式:
      • 进程获得处理机后,一直运行直至进程完成,或发生某事件而阻塞,才把处理机分配给其他进程。不允许其他进程抢占分配的处理机;
    • 抢占式
      • 允许调度程序,根据某种原则去暂停正在执行的进程,将已分配给该进程的处理机,分配给另一进程;
      • 优先级算法、短作业优先算法、时间片原则;
  • 各系统调度算法的目标

    • 批处理系统🤏:处理机利用率、系统吞吐量、平均周转时间短;
    • 分时系统:(时间片) 响应时间快、均衡性;
    • 实时系统:截止时间的保证、可预测性;

3.2 调度算法评价指标🔥🔥

  1. 以下是非抢占式的FCFS
进程到达时间运行时长开始运行时间结束时间等待时间✅周转时间🔥带权周转🔥
P1已知已知到达开始+运行开始-到达结束-到达周转/运行
P2已知已知上个结束开始+运行开始-到达结束-到达周转/运行
  • 周转时间
    • 平均周转时间🔥:∑周转时间÷n;
    • 平均带权周转时间🔥:∑带权周转时间÷n
  • 等待时间
  1. 也可用甘特图计算;

3.3 进程调度算法🔥

  1. 先来先服务FCFS

    • 按作业到达先后顺序;
    • 画甘特图
  2. 短作业优先SJF

    • 非抢占式

      • 先看到达的进程,运行时间最短的先;
      • 运行完,再看到达的进程,再挑选;
    • 抢占式:

      • 先看到达的进程,运行时间最短的先;
      • 运行时边看到达的进程;
      • 有比当前进程剩余时间片更短的进程到达时
  3. 优先级调度PR

    • 抢占式
    • 非抢占式
  4. 时间片轮转调度RR

    • 专为分时系统、抢占式;

3.4 死锁🔥

  • 定义🔥:一组等待的进程,每个进程持有资源,并且等待着组里其他进程所持有的资源,而陷入僵局,若无外力作用,这些进程将无法推进

  • 可抢占和不可抢占

    • 可抢占资源:如处理机和主存;
    • 不可抢占资源:如打印机、磁带机,分配后不能打断,不能收回,用完后释放;
  • 死锁原因✅:

    1. 竞争不可抢占资源;
    2. 竞争临时资源:一个进程需要另一个进程的结果;
    3. 进程推进顺序不当:请求和释放顺序不当;
  • 产生死锁的必要条件🔥🔥

    1. 互斥:某段时间内,某资源只能被一个进程占用;
    2. 请求保持
      • (吃着碗里的看着锅里的)
      • 一个至少持有一个资源的进程,等待其他进程所持有的资源;
    3. 不可抢占:进程已获得资源,未使用完前,不能被剥夺,只能在使用完释放
    4. 循环等待:等待资源的进程间存在环;(哲学家就餐)
  • 预防死锁的办法🔥(第一句即可)

    1. 预防死锁破坏必要条件的一个或几个;
      • 请求保持:获得初期便开始运行,逐步释放已用完的资源,再请求新资源;
    2. 避免死锁:在资源动态分配时,防止系统进入不安全状态;
      • 必须声明要申请的资源最大数n;
      • n小于进程数m-1,除自己;
      • 银行家算法,安全性算法;
    3. 检测死锁允许系统运行过程中发生死锁,但及时检测死锁发生;
    4. 解除死锁:检测到死锁发生时,采取相关措施,将进程从死锁的状态解脱出来;

四、存储器管理

理解系统存储器层次,围绕存储的组织结构,地址映射管理、内存三种调度算法、虚拟内存,分页、分段页面管理,非竞争条件的组织方式;

内存如何分配 、怎么回收 分配算法⽐较重要‼

内存不够下,页面置换机制及各种算法;

4.1 存储器的层次结构🤏

  • 分类:

    • 主存:cache高速缓存、主存储器、磁盘缓存;

    • 辅存:固定磁盘,移动存储介质;

    • cache:寄存器与存储器之间;
      在这里插入图片描述

4.2 程序的装入和链接

  • 程序的运行步骤

    1. 编译:对源程序就行编译,生成若干目标模块
    2. 链接:将目标模块与所需库函数链接在一起,形成装入模块;
    3. 装入:将装入模块装入内存中;
  • 重定位/地址变换:逻辑地址➡物理地址;

    • 编译后使用逻辑地址;
    • 静态~:装入时,变成物理地址;
    • 动态~:运行时,才变成物理地址;
  • 物理与逻辑地址

    • 物理地址:绝对地址;
    • 逻辑地址:虚拟地址,相对地址,程序编译后使用相对0字节的地址;
  • 内存保护的实现:硬件

    • 基地址寄存器:存放基地址,最小的合法物理地址;
    • 界限寄存器:存放合法的地址范围;

4.3 对换与覆盖

  • 对换/置换🤏

    • 把内存中,暂时不用或不能运行的程序和数据,调到外存以便腾出足够空间,给已具备运行的进程,或进程所需的程序和数据,调入内存
  • 对换类型

    • 整体对换:以进程为单位;
    • 部分(分段)对换:以“页”或“段”为单位,支持虚拟存储系统;
  • 覆盖

    • 解决程序大小超过物理内存总和;
    • 只放任何时间都需要的指令和数据;

4.4 连续分配存储管理方式

  • 分类

    1. 单一连续分配
    2. 固定分区分配
      • 预先把内存空间,划分成若干个连续的区域;
      • 分区的大小固定;
      • 每个分区只能装一个作业;
    3. 动态分区分配
      • 顺序式分配算法🤏
        • 首次适应算法
          • 首地址递增的次序链接;低地址有小碎片;
        • 循环首次适应算法
          • 从上次空闲分区的下个空闲分区开始找;缺大的空闲分区;
        • 最佳适应算法
          • 空闲分区按大小排序,搜索整个序列,找到适合的、最小的
        • 最坏适应算法
          • 空闲分区按大小排序,搜索整个序列,找到适合的、最大的
      • 索引式分配算法🤏36页
        • 快速适应算法、伙伴系统和哈希算法
      • 分配内存、回收内存
      • 数据结构
        • 空闲分区表
        • 空闲分区链:因为已分配的分区,会把空闲区分割,需保存空闲分区的起始部分,弄成双向链表;
    4. 动态可重定位分区分配43
      • 碎片、紧凑;
  • 内存分配与回收

    • 内存分配:40页
    • 内存回收:42页
  • 动态分区分配算法流程;46页

4.5 分页存储管理方式🔥🔥

  • 概述:

    • 页框(物理块/页帧)
      • 内存分成固定大小的块,1KB~8KB;
      • 每个页框长度与的长度一致;
      • 进程(作业)的逻辑地址分成固定大小的块;
      • 数据块
      • 每个作业的页的编号从0开始;
    • 页内碎片
      • 进程的最后一页装不满,造成不可以碎片;
  • 分页地址结构🔥
    在这里插入图片描述

    • 页号
      • 高20位,12-31;
      • 一个进程最多允许有1M(220)页
    • 位移量(页内地址):低12位,每页大小为4KB(212);
    • 求页号与页内地址🔥
      • 页号 = int(逻辑地址/页面长度);
      • 页内地址 = 逻辑地址%页面长度,即取余数(mod);
      • 物理地址 = 页面起始地址 + 页内地址;
  • 页表🔥

    • 记录每个页面内存中存放的位置;

    • 每个进程有一张页表,在表里有对应的物理块号

    • 保存在主存中

    • 页表寄存器指向页表的起始地址与长度;

    • 🔥一次数据/指令访问,需要两次内存访问,一次访问页表;
      在这里插入图片描述

  • 基本地址变换结构
    在这里插入图片描述

  • 快表的地址变换结构🔥

    • 快表/联想寄存器:来存放当前访问的若干页表项,比内存快;
    • 快表中存放页表的一部分副本
    • 有效访问时间EAT🔥🔥:
      • 访问快表需要时间λ,访问一次内存时间t,快表命中率a;
      • 基本地址变换EAT = 2t;
      • 快表地址变换EAT🔥
        • 命中λ*a + 未命中访问页表(1–a)(t+λ) + 目标内存;
        • EAT = λ*a + (t+λ)(1–a) + t;

4.6 分段存储管理方式

  • 分段:将进程划分成若干段,为满足程序员的编程要求;

    • 通常用一个段号来代替段名,每个段都从0开始编址;
    • 段的长度各不相等;
    • 每个分段有一个连续的分区,进程的各个段可以离散的装入;
  • 段表:

    • 记录段长基址
  • 分段与分页对比🔥🔥

    • 分段比分页更容易实现信息的共享和保护
    分页分段
    信息单位
    信息完整性离散分配方式意义相对完整
    页/段的大小固定,由系统决定不固定,由程序员决定
    地址空间一维二维

五、虚拟存储器

抖动、非竞争条件的组织方式、页面置换机制及各种算法;

5.1 概述

  • 传统/常规:作业被一次性全部装入内存

  • 虚拟存储器✅:具有请求调入置换功能,在逻辑上对内存容量加以扩充;

  • 虚拟存储器实现:11页

    • 请求分页
    • 请求分段
    • 段页式
  • 页面调入方法

    • 查找所需页在磁盘上的位置
    • 查找内存空闲块:
      • 如果有空闲块,就直接使用它;
      • 如果没有空闲块,使用页面置换算法选择一个“牺牲”内存块;
      • 将“牺牲”块的内容写到磁盘上,更新页表和物理块表。
    • 将所需页读入(新)空闲块,更新页表
    • 重启用户进程。
  • 缺页率🔥

    • 访问页面成功(在内存)的次数S
    • 访问页面不成功(缺页/不在内存)的次数F
    • 总访问次数 A = S+F
    • 缺页率 f = F/A

5.2 页面置换算法🔥

  1. 最佳置换算法OPT
    • 置换,之后最长时间不被使用的页
  2. 先进先出FIFO
    • 淘汰最先进入内存到页面。
  3. 最近最久未使用LRU
    • 硬件支持:具有最小数值的寄存器所对应的页面为淘汰页
  4. 最少使用LFU
  5. CLOCK置换算法
    • 访问位A与修改位M;置换时,循环依次查找第1类、第2类页面,找到为止🔥;
    • 第一类(A=0,M=0):最佳淘汰;
    • 第二类(A=0,M=1):次淘汰;
    • 第一类(A=1,M=0):可能被访问;
    • 第一类(A=1,M=1):经常访问;
  6. 页面缓冲算法PBA
    • 设置两个链表:
    • ①空闲页面链表:保存空闲物理块
    • ②修改页面链表:保存已修改且需要被换出的页面,等被换出的页面数目达到一定值时,再一起换出外存,

5.3 抖动与工作集🔥

  • 抖动🔥:

    • 如果多道程度过高,页面在外存与内存间频繁调度,甚至调度页面时间大于进程实际运行时间,系统效率急剧下降甚至崩溃;
  • 产生抖动的原因

    • 根本原因(同上)
      • 同时在系统中运行的进程数太多;
      • 因此分配给每个进程的物理块少,频繁缺页,需要频繁调度页面进内存;
    • 与系统为进程分配多少物理块有关系;

🎈剩下部分的笔记较为粗糙,这里就不放出来了~

  • 39
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值