操作系统概述 CPU篇
学习思路
整个操作系统的知识串
- 取指执行(使用cpu和内存)
- 使用cpu
- 合理利用cpu资源
- cpu执行多个进程(线程中断切换 )
- 线程如何切换(调度)
- 切换时需要保存当前状态(信号量)
- 信号量不允许多个进程同时操作(临界区,容易产生死锁)
- 死锁处理
- 使用内存
- 磁盘换入内存
- 内存换出到磁盘
- 磁盘的使用
- 磁盘到文件视图
什么是操作系统
和硬件交流的软件,应用程序通过操作系统和硬件交流,操作系统拥有硬件的访问权,可以执行机器能够运行的任何指令
计算机的两种运行模式
-
内核态
操作系统运行在内核态中
-
用户态
软件的其余部分运行在用户态下
内核
内核是应用连接硬件设备的桥梁
内核的功能
- 进程调度能力:管理进程、线程,决定那个进程、线程使用CPU
- 内存管理能力:管理内存,决定内存的分配和回收
- 硬件通信能力:管理硬件设备,为进程和硬件设备之间提供通信能力
- 用户与操作系统的接口:提供系统调用
内核具有很高的权限,可以控制CPU、内存、硬盘等硬件,所以大部分操作系统把内存分成了内核空间和用户空间,内核空间只允许内核程序访问,用户空间给应用程序访问
操作系统学习目标
组成部分
- CPU管理
- 内存管理
- 终端管理
- 磁盘管理
- 文件系统
- 进程管理
- 电源管理
- 设备驱动程序
- 网络管理
- 多核管理
计算机的启动过程
启动时,bios会执行bootsetup,bootsetup将系统代码加载到内存中,然后进行初始化
操作系统的接口
用户通过命令行,图形按钮和应用程序使用计算机
- 命令行方式:
cpu管理
- cpu设计时,为了充分利用cpu的性能,将多个程序交替执行
- 也就是多个程序执行时(并发:同时开始,交替执行),会大量消耗cpu性能
- 管理cpu就是要让cpu并发执行程序,提高cpu的执行效率
进程的概念
为了和静态的未运行的程序区分而引入的概念,意为运行中的程序
进程和静态程序的区别:进程需要记录程序执行的状态,而静态程序则不需要,因为cpu会并发运行程序,当切换到其他进程时,需要记录当前进程的状态,否则再次切换回改进程时,就无法继续运行,报错或者再次从头开始执行
多进程图像
进程将资源和指令分开,进程=资源+指令执行序列
交替的三个部分
- 队列
- 调度
- 切换
用户级线程
用户级线程通过系统调用引起的中断( fork() )进入到内核
进程
进程由资源和执行序列组成
线程
线程就是进程中的执行序列
线程切换(切换五段论)
线程切换流程:
- 从线程1的用户栈切换到线程1的内核栈
- 从内核栈切换到tcb
- tcb切换到线程2
- 线程2的tcb切换到线程2的内核栈
- 线程2的内核栈切换到用户栈,完成线程的切换
操作系统的进化
- 利用CPU
- 合理利用CPU性能(多线程切换进程)
- 扩展功能
线程调度
- 时钟中断(每隔相同时间定时进行线程切换)
调度算法
- 先来后到,按照指令到达时间先后顺序执行
- 短作业优先,按照指令的完成时间从短到长的顺序执行,可以减少周转时间
- 按照时间片来轮转调度
- 优先级,按照指令的轻重缓急的顺序执行,前台优先级偏高,后台优先级偏低,但不绝对,需要动态提升后台任务优先级
- 将以上几种调度算法结合,以时间片轮转调度为主,其他调度算法为辅,互相补足,才能使得线程合理执行任务,并充分发挥CPU的性能
调度函数
counter作为优先级和时间片,等待时间越久,优先级越高
- 先循环找出counter最大的任务
- 将任务的counter减半并且加上初始的counter
- 这样会将io任务的优先级提升,io操作又对应着前台任务
小知识:乘二和除二的次幂,位运算快于乘除
进程同步和信号量
多进程共同完成一个任务
- 司机和售票员,司机负责启停车辆,售票员负责开关门和售票,互相等待并发送信号
生产者-消费者实例
缓存区满–》生产者要停,缓存区空–》消费者要停
信号量临界区保护
为什么要保护临界区
因为信号量作为共享数据,多个进程同时操作,会使得信号量的值无法保证其准确性
直观解决方案:
在写共享变量empty时组织其他进程访问该变量
临界区:
一次只允许一个进程进入到该进程的一段代码
临界区的代码保护原则
- 互斥进入
- 有空让进
- 有限等待
死锁处理
定义:多个进程由于互相等待对方持有的资源而造成的谁都无法执行的情况叫死锁
成因:资源的互斥使用,进程占用资源不释放,又去申请其他资源
必要条件
- 互斥使用,资源的固有特性
- 不可抢占,资源只能自愿放弃
- 请求和保持,进程必须占有资源,又申请其他资源
- 循环等待,资源分配存在环路
死锁的处理
- 死锁的预防:破坏死锁出现的条件
- 执行进程前,一次性申请所有资源,避免再次申请资源
- 需要预知未来,编程困难
- 申请的资源长时间不用,资源利用率低
- 对资源类型排序,申请资源必须按照顺序进行,避免环路
- 资源浪费
- 执行进程前,一次性申请所有资源,避免再次申请资源
- 死锁避免:检测资源请求,如果会造成死锁就拒绝
- 死锁判断,如果进程按照执行序列执行,则系统处于安全状态,为安全序列(银行家算法,代价较大)
- 死锁检测+恢复:检测到死锁,让一些进程回滚,释放资源
- 发现死锁之后再处理,定期检测或发现资源利用率低时检测
- 如何选择回滚进程?
- 发现死锁之后再处理,定期检测或发现资源利用率低时检测
- 死锁忽略:就好像没有出现死锁一样(如太阳上发生火灾)
- 对于常用的pc,可以使用死锁忽略,直接重启即可解决
- 重启解决99%问题
操作系统概述 内存篇
内存的使用与分段
重定位:修改程序中的地址,将逻辑地址修改为空闲的逻辑地址
- 载入时重定位
- 如果程序载入之后还需要移动(内存和磁盘之前交换)就会导致错误
- 运行时重定位
- 地址翻译:每执行一条指令都要从逻辑地址算出物理地址(逻辑地址的偏移量+这段指令的初始物理地址)
程序由若干部分组成,每个段都有自己的特点
- 主程序——只读
- 变量集——可写
- 函数库——可能不载入
- 堆——
- 栈——单向增长
因为程序的各个部分对读写的要求不同,所以将程序加载到内存中时,会将各段分别放入内存,即分段
内存分区与分页
分区
- 固定分区:将内存等分成K个分区(无法适应不同的程序)
- 可变分区:根据需求分区
分区适配
- 首先适配,找第一个满足申请空间的空闲分区
- 最佳适配,找到满足申请空间的空闲分区中和申请分区大小最接近的分区
- 最差适配,找到满足申请空间的空闲分区中和申请分区大小差别最大的分区
有时候需要很大的内存块,有时又很好,分区已经无法完美的适配,所以引入了分页的概念
内存碎片
总空闲空间大于申请空间,但没有一个连续的空闲分区大于申请空间
- 将空闲分区合并,移动已用的内存段(内存紧缩,花费时间较多)
分页
解决内存分区导致的内存效率问题
操作系统初始化时,将内存等分成一页一页,然后申请空间时,也按照需要的页向上取整并分配空间,一个进程最多浪费一页空间,且不用进行内存紧缩
多级页表和快表
为了提高内存的空间利用率,页应该小,页表就会更大
解决办法:
- 用到的逻辑页才加入到页表中(页号必须连续,导致该种方法失效)
- 多级页表(参考书的目录,优化成多级页表,保证了页号连续,也占用较少内存)
- 多级页表提高了空间效率,但是也增加了查询页表的次数,再结合硬件设计,使用寄存器,根据页号一次直接找到对应的页
段页结合的实际内存管理模式
将程序载入内存
- 将程序放入虚拟地址中
- 在段表中记录相关地址信息
- 将虚拟地址上的程序放到物理地址中
- 在页表中记录i相关地址映射信息
- 修改物理地址中的程序地址的基址
内存换入-请求调页
内存换入,指的是当虚拟内存(仓库)大于物理内存(店面)时,程序想要访问资源,发现物理内存中没有,将磁盘中的页换到内存中(请求调页),并做好映射的过程
内存换出
内存换入时,内存是有限的,不能无限量换入,需要淘汰一页,换出到磁盘,再换入
换出算法:
- 先入先出
- 缺点:可能刚换出的资源又马上需要加载进来
- 选最后使用的页淘汰
- 缺点:需要预知未来对页进行淘汰
- 选最长时间未使用的页进行淘汰
- 实现一:每页维护一个时间戳(维护时间戳的代价太大)
- 实现二:维护一个页码栈,先入先出(栈底的页先淘汰,地址访问和修改栈的代价太大)
- 实现三:给每个页加一个引用位(使用时置为1,不用置为0),选择淘汰页时,循环遍历引用位,如果为1,将其置为0,不换出,如果为0,换出(每次访问页,只需要将1改成0,代价小,但当1较多时,就没有换出)
- 实现四:再加一个扫描指针,定时将1置为0(clock算法)
操作系统概述 io篇
io与显示器
cpu通过总线,往外设的寄存器中写入指令,外设再执行对应的指令,执行完向cpu发出中断,表示已经执行完该指令
不论什么设备,操纵外设都是open,read,write,close几个系统调用接口,不同的设备对应不同的设备文件
printf的过程
- printf库函数
- write系统调用
- crw_table[字符设备接口]
- tty设备写
- 显示器写
键盘
操作系统概述 磁盘篇
生磁盘的使用
磁盘:磁盘访问的单位是扇区,每个扇区512字节
磁盘io的过程:控制器–》寻道–》旋转–》传输
磁盘的结构,由多个盘面堆叠,每个盘面有磁头和磁道,磁头在磁道上运动,每个磁道有多个扇区,磁生电读取,电生磁写入
使用磁盘,往控制器中写柱面、磁头、扇区、缓存位置
磁盘调度算法:
- 先来先处理
- 缺点:磁头移动的磁道较多,效率低
- 短寻道优先,离当前扇区最近的请求优先处理
- 缺点:多数请求在磁道的中间位置,在磁道两头位置的请求就会被中间位置的请求给截断,等中间位置的请求结束,才会轮到磁道两头位置的请求
- 电梯算法,中途不返回,保证了公平性,磁头也不存在来回扫描的情况
- 电梯算法优化,当磁头到了磁道的末端,直接回到另外一段,再次扫描并且中途不折返
生磁盘的使用
- 进程得到盘块号,算出扇区号
- 用扇区号发出请求,用电梯算法添加到队列中
- 进程到此就睡眠
- 磁盘中断处理请求
- 处理磁盘请求,算出chs(磁道,盘面,扇区)
- 处理完成后再次进行中断处理,唤醒进程
从生磁盘到文件
文件,是对磁盘使用的第三层抽象,普通用户无法通过扇区和盘块号访问磁盘,所以需要引入文件的概念
文件,在用户的眼里是字符序列,磁盘上的文件就是要建立字符流到盘块集合的映射关系,操作系统负责维护这个映射
文件的实现:
- 连续盘块
- 缺点:当申请的磁盘块集合空间不够时,需要整体迁移到足够大的空间处
- 链式盘块
- 缺点:需要读取完上一个盘块,才能找到下一个盘块,效率低
- 索引盘块
- 多级索引的盘块,这是系统实际使用的实现方式
- 优点,可以表示大文件,小文件高效访问,中等文件的访问也不慢
操作系统概述 终章
- 多进程(使用cpu)
- 取指执行