概念
- 负责管理协调硬件、软件等计算机资源的工作
- 为上层用户、应用程序提供简单易用的服务
- 是一种系统软件
功能和目标
- 资源的管理者
- 处理机管理:进程管理(进程控制、进程同步、进程通信、死锁处理、处理机调度)
- 存储器管理:内存管理(内存分配、地址映射、内存保护与共享、虚拟内存)
- 文件管理:文件存储空间的管理、目录管理、文件读写管理和保护
- 设备管理:完成用户的I/O请求,方便用户使用各种设备,并提高设备的利用率。主要包括缓冲管理、设备分配、设备处理、虚拟设备
- 向用户提供服务
- 命令接口(联机命令接口、脱机命令接口)
- 程序接口(由一组系统调用组成)
- GUI用户图形界面
- 对硬件机器的扩展
- 扩充机器
操作系统的特征
并发、共享、虚拟、异步
并发
两个或多个事件在同一时间间隔内发生。宏观上是同时发生的,但微观上是交替发生的。常考易混概念——并行:指两个或多个事件在同一时刻同时发生。
单核CPU同一时刻只能执行一个程序,各个程序只能并发地执行
多核CPU同一时刻可以同时执行多个程序,多个程序可以并行地执行
共享
共享即资源共享,是指系统中的资源可供内存中多个并发执行的程序共同使用。
两种资源共享方式:互斥共享方式、同时共享方式
虚拟
虚拟是指将一个物理上的实体变成若干个逻辑上的对应物。
虚拟技术:空分复用技术(如虚拟存储器技术)、时分复用技术(如虚拟处理器)
异步
异步是指在多道程序环境下,允许多个程序并发执行,但是由于资源有限,进程执行不是一贯到底的,而是走走停停,以不可预知的速度向前推进,这就是进程的异步性。
操作系统的运行机制
两种指令:处理器能识别、执行的最基本命令
- 特权指令:如内存清零指令
- 非特权指令如普通的运算指令
两种处理器状态(用程序状态字寄存器PSW中的标志位识别)
- 核心态(管态):特权指令、非特权指令都能执行
- 用户态(目态):只能执行非特权指令
两种程序
内核程序、应用程序
操作系统的内核
内核是计算机上配置的底层软件,是操作系统最基本、最核心的部分。
操作系统的体系结构
大内核、微内核
中断
- 当中断发生时,CPU立即进入核心态
- 当中断发生后,当前运行的进程暂停运行,并由操作系统内核对中断进行处理
- 对于不同的中断信号,会进行不同的处理
中断:内中断和外中断
系统调用
如果一个进程在用户态需要使用内核态的功能,就进行系统调用从而陷入内核,由操作系统代为完成。
操作系统作为用户和计算机之间的接口,需要向上提供简易的服务。主要包括命令接口和程序接口。其中程序接口由一组系统调用组成。(核心态)
大内核
大内核是将操作系统功能作为一个紧密结合的整体放到内核。由于各模块共享信息,因此有很高的性能。
微内核
将一部分操作系统功能移出内核,从而降低内核的复杂性。在微内核结构下,操作系统被划分为小的、定义良好的模块,只有微内核这一模块运行在内核态,其余模块运行在用户态。
中断分类
- 外中断:由CPU执行指令以外的事件引起。
- 异常:由CPU执行指令的内部事件引起,如非法操作码、地址越界、算术溢出等。
- 陷入:在用户程序中使用系统调用。
进程是资源分配的基本单位。
线程是独立调度的基本单位。一个进程中可以有多个线程,他们共享资源。
区别
- 拥有资源:进程是资源分配的基本单位,但是线程不拥有资源,线程可以访问隶属进程的资源。
- 调度:线程是独立调度的基本单位,在同一进程中,现成的切换不会引起进程切换,从一个进程中的线程切换到另一个进程中的线程时,会引起进程的切换。
- 系统开销:由于创建或撤销进程时,系统都要为之分配或回收资源,如内存空间、I/O设备等,所付出的开销远大于创建或撤销进程时的开销。类似的,在进程切换是,涉及当前执行进程CPU环境的保存及新调度进程CPU环境的设置,而线程切换时只需保存和设置少量寄存器内容,开销很小。
- 通信方面:线程间可以直接读写同一进程中的数据进行通信,但是进程通信需要借助IPC。
进程状态的切换
- 就绪状态(ready):等待被调度
- 运行状态(running)
- 阻塞状态(waiting):等待资源
进程调度算法
- 批处理系统
- 先来先服务
- 短作业优先
- 最短剩余时间优先
- 交互式系统
- 时间片轮转
- 优先级调度
- 多级反馈队列(时间片轮转和优先级调度的结合)
- 实时系统
进程同步
- 临界区:对临界资源进行访问的那段代码
- 同步与互斥:多个进程合作产生直接制约关系,有先后执行顺序;同一时刻只有一个进程进入临界区
- 信号量:可以对其执行down和up操作。
- 管程:在一个时刻只能有一个进程使用管程。管程引入条件变量以及相关的操作:wait()和signal()来实现同步操作。对条件变量执行wait()操作会导致调用进程阻塞,让管程让出来给另一个进程。signal()操作用于唤醒被阻塞的进程。
进程通信
进程间传输信息
- 管道:通过调用pipe函数创建,fd[0]用于读,fd[1]用于写。
- 限制是:只支持半双工通信(单向交替传输);只能在父子或兄弟进程中使用。
- FIFO:命名管道,去除了只能在父子进程中使用的限制
- 消息队列
- 消息队列可以独立于读写进程存在,从而避免了 FIFO 中同步管道的打开和关闭时可能产生的困难;
- 避免了 FIFO 的同步阻塞问题,不需要进程自己提供同步方法;
- 读进程可以根据消息类型有选择地接收消息,而不像 FIFO 那样只能默认地接收。
- 信号量:计数器
- 共享存储:最快的进程通信(IPC)
- 套接字:可以用于不同机器间的进程通信
死锁发生的必要条件
- 互斥:每个资源要么已经分配给了一个进程,要么就是可用的
- 占有和等待:已经得到了某个资源的进程可以再请求新的资源
- 不可抢占:只能被占有它的进程显式的释放
- 环路等待:进程组成环路
处理方法
1.鸵鸟策略
不采取措施
2.死锁检测和死锁恢复
检测到死锁后采取措施进行恢复
- 每种类型一个资源的死锁检测:通过检测有向图是否存在环。深度优先算法。
- 每种类型多个资源的死锁检测:每个进程最开始时都不被标记,执行过程有可能被标记。当算法结束时,任何没有被标记的进程都是死锁进程。
3.死锁恢复
- 利用抢占恢复
- 利用回滚恢复
- 通过杀死进程恢复
死锁预防
- 破坏互斥条件
- 破坏占有和等待条件
- 破坏不可抢占条件
- 破坏环路等待:编号
死锁避免
- 安全状态
- 单个资源的银行家算法
- 多个资源的银行家算法
虚拟内存
让物理内存扩充成更大的逻辑内存,从而让程序获得更多的可用内存。
分页系统地址映射
内存管理单元(MMU)管理着地址空间和物理内存的转换,其中的页表(Page table)存储着页(程序地址空间)和页框(物理内存空间)的映射表。
一个虚拟地址分成两个部分,一部分存储页面号,一部分存储偏移量。
页面置换算法
访问的页面不在内存中,将该页调入内存,如果无空闲空间,系统调出一个页面腾空间。
使页面置换频率最低(缺页率最低)
- 最佳(OPT):被换出的页面是最长时间不再被访问的,保证最低的缺页率。
- 最近最久未使用(LRU):链表实现
- 最近未使用(NRU)
- 先进先出(FIFO):选择换出的页面是最先进入的页面
- 第二次机会算法
- 时钟
分段
虚拟内存采用的是分页技术,也就是将地址空间划分成固定大小的页,每一页再与内存进行映射。分段的做法是把每个表分成段,一个段构成一个独立的地址空间。每个段的长度可以不同,并且可以动态增长。
段页式
程序的地址空间划分成多个拥有独立地址空间的段,每个段上的地址空间划分成大小相同的页。这样既拥有分段系统的共享和保护,又拥有分页系统的虚拟内存功能。
分页和分段的比较:
- 对程序员的透明性:分页透明,但是分段需要程序员显式划分每个段。
- 地址空间的维度:分页是一维地址空间,分段是二维的。
- 大小是否可以改变:页的大小不可变,段的大小可以动态改变。
- 出现的原因:分页主要是用于实现虚拟内存,从而获得更大的地址空间;分段是为了使程序和数据可以被划分为逻辑上独立的地址空间并且有助于共享和保护。
磁盘的结构
- 盘面(Platter):一个磁盘有多个盘面;
- 磁道(Track):盘面上的圆形带状区域,一个盘面可以有多个磁道;
- 扇区(Track Sector):磁道上的一个弧段,一个磁道可以有多个扇区,它是最小的物理储存单位,目前主要有 512 bytes 与 4 K 两种大小;
- 磁头(Head):与盘面非常接近,能够将盘面上的磁场转换为电信号(读),或者将电信号转换为盘面的磁场(写);
- 制动手臂(Actuator arm):用于在磁道之间移动磁头;
- 主轴(Spindle):使整个盘面转动。
磁盘调度算法
读写一个磁盘块的时间的影响因素有:
- 旋转时间(主轴转动盘面,使得磁头移动到适当的扇区上)
- 寻道时间(制动手臂移动,使得磁头移动到适当的磁道上)
- 实际的数据传输时间
其中,寻道时间最长,因此磁盘调度的主要目标是使磁盘的平均寻道时间最短。
- 先来先服务(FCFS):按照磁盘请求的顺序进行调度
- 最短寻道时间优先(SSTF):优先调度与当前磁头所在磁道距离最近的磁道
- 电梯算法(SCAN):总是按照一个方向进行磁盘调度,直到该方向上没有未完成的磁盘请求,然后改变方向。
编译系统
- 预处理阶段:处理以 # 开头的预处理命令;
- 编译阶段:翻译成汇编文件(.s);
- 汇编阶段:将汇编文件翻译成可重定位目标文件(.o);
- 链接阶段:将可重定位目标文件和 printf.o 等单独预编译好的目标文件进行合并,得到最终的可执行目标文件。
静态链接
静态链接器以一组可重定位目标文件为输入,生成一个完全链接的可执行目标文件作为输出。链接器主要完成以下两个任务:
- 符号解析:每个符号对应于一个函数、一个全局变量或一个静态变量,符号解析的目的是将每个符号引用与一个符号定义关联起来。
- 重定位:链接器通过把每个符号定义与一个内存位置关联起来,然后修改所有对这些符号的引用,使得它们指向这个内存位置。
目标文件
- 可执行目标文件:可以直接在内存中执行;
- 可重定位目标文件:可与其它可重定位目标文件在链接阶段合并,创建一个可执行目标文件;
- 共享目标文件:这是一种特殊的可重定位目标文件,可以在运行时被动态加载进内存并链接;
动态链接
静态库有以下两个问题:
- 当静态库更新时那么整个程序都要重新进行链接;
- 对于 printf 这种标准函数库,如果每个程序都要有代码,这会极大浪费资源。
共享库是为了解决静态库的这两个问题而设计的,在 Linux 系统中通常用 .so 后缀来表示,Windows 系统上它们被称为 DLL(数据库模式定义语言Data Definition Language)。它具有以下特点:
- 在给定的文件系统中一个库只有一个文件,所有引用该库的可执行目标文件都共享这个文件,它不会被复制到引用它的可执行文件中;
- 在内存中,一个共享库的 .text 节(已编译程序的机器代码)的一个副本可以被不同的正在运行的进程共享。
参考资料
https://github.com/CyC2018/CS-Notes/blob/master/notes/%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%20-%20%E7%9B%AE%E5%BD%95.mdgithub.com