1. 操作系统概述

1.1. 基本特征:并发、共享、虚拟和异步。

① 并发:宏观上一段时间能同时运行多个程序。
② 共享:系统中的资源可以同时被多个并发进程共同使用。

  1. 互斥共享:临界资源,如打印机。
  2. 同时共享:

③ 虚拟:把物理实体转换为多个逻辑实体。虚拟技术:时/空 分复用技术

  1. 时分复用技术:多个进程能在同一个处理器上并发执行使用了时分复用技术,每个进程轮流占用处理器,每次只执行一小个时间片并快速切换;
  2. 空分复用技术:虚拟内存使用了空分复用技术,它将物理内存抽象为地址空间,每个进程都有各自的地址空间。地址空间的页被映射到物理内存,地址空间的页并不需要全部在物理内存中,当使用到一个没有在物理内存的页时,执行页面置换算法,将该页面换到内存中。

④ 异步:进程不是一次性执行完,而是走走停停,以不可知的速度向前推进。

1.2. 基本功能

1.2.1.进程管理

  1. 进程控制:
  2. 进程同步:
  3. 进程通信:
  4. 死锁处理:
  5. 处理机调度:

1.2.2. 内存管理

  1. 内存分配:
  2. 地址映射:
  3. 内存保护和共享:
  4. 虚拟内存:

1.2.3. 文件管理

  1. 文件存储空间的管理:
  2. 目录管理:
  3. 文件读写管理和保护

1.2.4. 设备管理

完成用户的I/O请求,方便用户使用各种设备,并提高设备的利用率。

  1. 缓冲管理
  2. 设备分配
  3. 设备处理
  4. 虚拟设备

1.3. 系统调用

如果一个进程在用户态需要使用内核态的功能,就进行系统调用从而陷入内核,由操作系统代为完成。

1.4. 宏内核和微内核:

1.4.1. 宏内核

将操作系统功能作为一个紧密结合的整体放到内核。

  1. 优点:因为各模块共享信息,因此有很高的性能;
  2. 缺点:随着功能的增加,内核的复杂性也随之增加。

1.4.2. 微内核

在微内核结构下,操作系统被划分成小的、定义良好的模块,只有微内核这一个模块运行在内核态,其他都运行在用户态。

  1. 优点:将一部分操作系统功能移除内核,降低了内核的复杂度;
  2. 缺点:频繁地在用户态和核心态之间进行切换,会有一定的性能损失。

1.5. 中断

① 外中断:由CPU执行指令以外的事件引起,如I/O完成中断、控制台中断(ctrl+Z)等
② 异常:由CPU执行指令的内部事情引起,如非法操作码、地址越界、算术溢出等
陷入:在用户程序中使用系统调用

2. 进程管理

2.1. 进程与线程

① 进程:资源分配的基本单位。动态的。
② 线程:CPU调度的基本单位。一个进程可以有多个线程,他们共享进程资源。
③ 区别:

  1. 拥有资源:进程是资源分配的基本单位,但是线程不拥有资源,线程可以访问隶属进程的资源;
  2. 调度:线程是独立调度的基本单位。在同一个进程中,线程的切换不会引起进程的切换;不同进程对应的线程切换会引起进程的切换。
  3. 系统开销:
    a. 进程的创建和撤销>线程的创建和撤销。进程系统开销体现在:内存空间、I/O设备等。
    b. 进程的切换>线程的切换。
    a) 进程的切换开销:当前执行进程CPU环境的保存+新调度进程CPU环境的设置;
    b) 线程的切换开销:只需要保存和设置少量寄存器内容。
  4. 通信方面:线程间可以通过直接读写同一个进程中的数据进行通信;但是进程通信需要借助IPC(Inter-Process Communication,进程间通信).

2.2. 进程状态切换(5种)

① 创建
② 就绪:等待被调度(缺CPU时间)
③ 运行
④ 阻塞:等待资源(缺其他资源,非CPU)
⑤ 终止

2.3. 进程调度算法

不同环境的调度算法目标不同,因此需要针对不同环境来讨论调度算法

① 批处理系统

目标:保证吞吐量和周转时间。

  1. 先来先服务 First Come First Serverd(FCFS):表面上很公平。实际上,利于长作业,不利短作业
  2. 短作业优先 Shortest Job First(SJF):非抢占,长作业可能会饿死。
  3. 最短剩余时间优先 Shorted Remaining Time Next (SRTN) :抢占,新的作业来到,其整个运行时间与当前进程的剩余时间作比较。优化了SJF算法吗?该挨饿的,还是老老实实的等着。

② 交互式系统

目标:快速的响应。

  1. 时间片轮转:当一个进程的时间片用完,会到就绪队列排队,把时间片分给队首的进程。时间片大小的设置,是该算法的重点。大、或者小都不好。
  2. 优先级调度:为每个进程分配一个优先级,按优先级调度。
  3. 多级反馈队列:动机,进程切换影响了效率。

③ 实时系统:分为硬实时(e.g., 航天系统)和软实时(e.g., Linux系统)。

2.4. 进程同步

控制多个进程按一定顺序执行

① 临界区:对临界资源进行访问的那段代码 ② 同步与互斥:

  1. 同步:多个进程因为合作产生直接制约关系,使得进程有一定的先后执行关系。
  2. 互斥:多个进程在同一时刻只有一个进程可以进入临界区。

③ 信号量:Semaphore
④ 管程:在一个时刻只能有一个进程使用管程。进程在无法继续执行的时候不能一直占用管程,否则其它进程永远不能使用管程。

2.5. 经典同步问题

① 生产者-消费者问题

  1. 要求:生产者制造商品的前提是:仓库没有满;消费者消费的前提:仓库没有空。

② 哲学家进餐问题

  1. 要求:同时拿起左右两支筷子,且左右没有人进餐

③ 读者-写者问题

  1. 可以有多人读操作;但是读的时候不能写,写的时候不准读和写。

2.6. 进程通信

进程间传输信息

① 管道:半双工通信、只能在父子/兄弟进程中使用。
② FIFO: 也称为命名管道,去除了管道只能在父子进程中使用的限制。
③ 消息队列:
④ 信号量:
⑤ 共享存储:
⑥ 套接字:与其它通信机制不同的是,它可用于不同机器间的进程通信。

3. 死锁

3.1. 必要条件:4个

① 互斥条件
② 等待与保持
③ 不可抢占
④ 环路等待

3.2. 处理方法:4种 3~6

3.3. 鸵鸟策略

① 假装没有发生问题
② 大多数操作系统,e.g., Unix、Linux和Windows,都是采用这种方法。

3.4. 死锁检测和死锁恢复

不试图阻止死锁,而是当检测到死锁发生时,采取措施进行恢复

① 每种类型一个资源的死锁检测:判断是否有环。有环即发生了死锁。深搜/拓扑排序。
② 每种类型多个资源的死锁检测:
③ 死锁恢复

3.5. 死锁预防

在程序运行之前预防发生死锁。

① 破坏互斥条件

② 破坏占用和等待条件:执行前请求所需要的全部资源。

③ 破坏不可抢占条件:

④ 破坏环路等待:给资源统一编号,进程只能按编号顺序请求资源。

  1. 比如A进程需要打印机和显示屏,B进程需要显示屏和打印机。则,不管其逻辑上的请求顺序,都必须按编号请求资源,比如,先请求显示屏,再请求打印机。

3.6. 死锁避免

在程序运行时避免发生死锁。

① 安全状态:如果没有死锁发生,并且即使所有进程突然请求对资源的最大需求,也仍然存在某种调度次序能够使得每一个进程运行完毕,则称该状态是安全的。
② 单个资源的银行家算法:
③ 多个资源的银行家算法

4. 内存管理

4.1. 虚拟内存

采用的分页技术

① 目的:为了让物理内存扩充成更大的逻辑内存,从而让程序获得更多的可用内存。
② 那么怎么扩充的呢?

  1. 操作系统把内存抽象成地址空间,每个程序拥有自己的地址空间,这个地址空间被分割成多个块,每一块称为一页。这些页被映射到物理内存,但不需要映射到连续的物理内存,也不需要所有页都必须在物理内存中。当程序引用不在物理内存中的页时,由硬件执行必要的映射,将缺失的部分装入物理内存,并重新执行失败的指令。
  2. 直观感受虚拟内存扩充逻辑内存的例子:
    例如有一台计算机可以产生 16 位地址,那么一个程序的地址空间范围是 0~64K。该计算机只有 32KB 的物理内存,虚拟内存技术允许该计算机运行一个 64K 大小的程序。
    因为,虚拟内存技术不需要所有页都必须在物理内存中,在用的时候调入进去就ok了。

4.2. 分页系统地址映射

① 内存管理单元(MMU)管理着地址空间和物理内存的转换,其中的页表(Page table)存储着页(程序地址空间)和页框(物理内存空间)的映射表。
② 虚拟地址 = 页面号 + 偏移量

4.3. 页面置换算法

使页面的置换频率最低。

① 最佳置换算法 Optimal Replacement Algorithm OPT

  • 所选择被换出的页面是最长时间内不被访问的页。
  • 是一种理论的算法,因为无法知道一个页面多长时间不再被访问。

② 最近最久未使用 Least Recently Used LRU

③ 最近未使用Not Recently Used NRU

  • 每个页有两个状态位:R与M。访问时 R=1,修改时 M=1. R位会定时清零。NRU 优先换出脏页面(R=0,M=1)。

④ 先进先出 First In First Out FIFO

  • 该页面会把经常被访问的页面换出,导致缺页率升高。

⑤ 第二次机会算法

  • 多给一次机会,当页面被访问时,修改其R=1,当需要替换的时候,轮到这个R=1的页时,就把它重新放到链表的尾部,就像刚被访问过一样,R=0.继续从链表的头部搜索。

⑥ 时钟 Clock

  • 第二次机会算法需要移动链表的元素(页),降低了效率。时钟算法,是构造一个环。让指针指向最老的那个页。(逻辑上的队首)

4.4. 分段

① 分段的做法是把每个表分成段,一个段构成一个独立的地址空间。每个段的长度可以不同,并且可以动态增长。

4.5. 段页式

① 程序的地址空间划分成多个拥有独立地址空间的段,每个段上的地址空间划分成大小相同的页。这样既拥有分段系统的共享和保护,又拥有分页系统的虚拟内存功能。

4.6. 分页和分段的比较

① 对程序员的透明性:分页透明,但是分段需要程序员显式划分每个段。
② 地址空间的维度:分页是一维地址空间,分段是二维的。
③ 大小是否可以改变:页的大小不可变,段的大小可以动态改变。
④ 出现的原因:分页主要用于实现虚拟内存,从而获得更大的地址空间;分段主要是为了使程序和数据可以被划分为逻辑上独立的地址空间并且有助于共享和保护。

5. 设备管理

主要是磁盘。

5.1. 磁盘结构:

① 盘面
② 磁道
③ 扇区
④ 磁头
⑤ 制动手臂
⑥ 主轴

5.2. 磁盘调度算法:

访问数据时间 = 主轴转动时间+寻道时间+数据传输时间

① 先来先服务
② 最短寻道时间优先:磁道远离磁头的请求会出现饥饿现象。
③ 电梯算法:磁头一次只往一个方向移动,直到没有该方向的磁道请求才往另一个方向,解决了饥饿问题。

6. 链接

(1) 在Unix系统上,编译器把源文件转换为目标文件:
① 预处理阶段:处理以#开头的预处理命令;
② 编译阶段:翻译成汇编文件;
③ 汇编阶段:将汇编文件翻译成可重定位目标文件;
④ 链接阶段:将可重定位目标文件和printf.o等单独预编译好的目标文件进行合并,得到最终的可执行目标文件。