第一章节
-
操作系统是软件
-
程序在执行之前需要程序放在内存中
-
功能是什么:
- 处理机制的管理:
- 进程控制
- 进程同步
- 进程通信
- 死锁处理
- 处理机调度
- 存储器管理:
- 提高内存利用率
- 内存的分配与回收
- 地址映射
- 内存保护与共享
- 内存扩充
- 文件管理:
- 计算机中的信息都是以文件的形式存在的
- 设备管理:
- 完成用户的 I/O 请求,方便用户使用设备、并提高设备的利用率
- 处理机制的管理:
-
目标:高效、安全向上层提供方便易用的服务
操作系统用作扩充机器没有任何软件支持的计算机(裸机)
实际呈现在用户面前的计算机系统是经过若干层软件改造的计算机。
操作系统将裸机改造成功能更强、使用更方便的机器。
我们将覆盖了软件的机器称为扩充机器或虚拟机
-
处理机 cpu
-
裸机 操作系统 软件之间的关系
-
看上面 操作系统回把硬件提供的服务进行封装,用户不需要去关心硬件怎么实现的只需要对操作系统发出指令
-
bat批处理命令
开始
-
首先操作系统的特征是什么
- 并发
- 共享
- 虚拟
- 异步
-
什么是并发 ?
并发就是宏观上同时发生 微观上交替发生
对于一个单核的 cpu 来说同一时刻只能执行一个程序各个程序只能去并发的执行
对于多核的 cpu 来水呢同一时刻可以执行多个程序,多个程序可以并行的去执行 -
共享特性?
就是资源共享 指的是系统中的资源可供多个并发程序的进程去共同使用
3.1 两种共享的方式?
- 互斥共享 一个时间段内有一个进程
- 同时共享 一个时间段内有多个进程
同时共享的同时,宏观上面是同时,微观上就是几个进程交替的去访问
互斥共享就比如手机打视频电话 QQ和微信只能一个
同时共享就比如 qq 和微信发送同时发送同一个文件看起来两个程序是同时在访问 其实就是两个进程交替着去访问
3.2 总结并发和共享
并发性就是说系统同时在执行多个程序
共享是说系统的资源能被内存里面多个并发程序访问
失去并发性共享性就失去了意义,失去了共享性并发性也没有意义
-
虚拟
虚拟就是值把物理上的实体变为若干个逻辑上对应物。
物理实体是现实中存在的,逻辑上的实体是用户感受到的
(一个程序需要放入内存并且分配给 cpu 才能去执行)
比如永劫无间需要两个 GB 的运行内存网易云需要 250 MB,QQ 需要 256 MB 还有游览器这个内存大户为什么能同时去运行呢?因为虚拟存储器技术(空分复用)
虚拟处理器技术:一个单核 cpu 为什么能同时运行多个软件呢?原因就是它 (时分复用技术)
两个虚拟技术 空分复用、时分复用 -
异步问题
什么是异步:多个程序环境下让他们并发运行,但是因为资源有限,进程的执行不是贯彻到底的而是走走停停
如进程 A | 1: 资源 1 B | 1: 有限资源
| 2: 有限资源 | 2: 资源 1
AB 并发执行 0-1 分钟 A 资源 1
1-2 分钟 B 有限资源
2-3 分钟 A 有限资源(等待 B)
3-4 分钟 B 资源 1
并发运行的程序会枪资源
只有系统有了并发性才能有可能导致异步性 -
单道批系统资源利用率低
输入 -> 计算机 -> 输出
1======= ======== 2======= ======== 3======= ========
上一个完成后下一个才可以输入 -
多道批
1 ======== ====
2============ ====
3============ ====
上一个输入完成 计算机在处理 就接着输入 -
分时操作系统
计算机 分时间为各个用户服务
好处:用户的请求可以被响应解决了人机交互
坏处:不能优先去处理紧急任务
改进坏处:不能优先去处理紧急任务 -
实时操作系统(及时性可靠性)
(1) 可以根据任务优先级去优先处理某些任务
操作系统的运行机制 总览
- 内核程序和应用程序
CPU 在生产时就划分了指令权限
内核程序是操作系统资源的管理者 可以使用特权指令
应用程序只能使用非特权指令 - CPU 的两种状态
(1) 内核态 核心态 管态
处于内核态说明此时正在运行的内核程序可以执行特权命令
(2) 用户态 目态
处于用户态时说明此时运行的是应用程序不可以特权
需要操作系统接入进行工作时 都会产生中断信号
中断和异常
中断:操作系统夺回 CPU 使用权
中断会让 cpu 从目态变为核心态
如果没有中断一个程序会一直在运行
- 内中断(也被称为异常)
与当前执行指令有关中断信号来自 CPU 内部- 陷入(应用程序故意引发的)
- 故障:错误条件引起,可能被内核程序修复的(缺页)
- 修复之后再把程序使用权给程序
- 终止:致命错误引发,cpu 无法修复,直接终止这个程序(整数除以 0、非法使用特权指令)
- 外中断
与当前执行指令无关来自 CPU 外部- 例如 时钟中断 每每间隔 50ms 就会发送中断信号
- I/O 中断 由输入输出设备发送的
不同中断信号需要不同的中断处理程序来处理
去中断向量表查询
系统调用
操作系统为用户提供使用计算机硬件系统的接口命令接口(用户通过控制台或终端输入操作命令,向系统提供各种服务要求)程序接口(由 系统调用 组成,用户在程序中使用这些系统调用来请求操作系统为其提供服务)图形接口 最常见的 图形用户界面 GUI (最终还是通过调用程序接口实现的)
凡是涉及共享资源的操作 内存、IO、文件 都要通过系统调用来进行处理
操作系统体系结构
操作系统包括
- 内核: 进程、存储器、设备、
时钟管理(利用时钟中断实现计时)
中断处理、原语(设备驱动、CPU 切换等)
什么是原语:特殊的程序是原语具有原子性运行时不可以被中断的程序 - 非内核:如 GUI
有的操作系统不把进程管理资源管理设备管理放在内核当中去↓所以
有两种操作系统内核的设计方法- 一种叫做大内核
- 一种是微内核只保留和硬件相关的
注:使用微内核设计和硬件不是很直接会被运行在用户态,也就是说它不 属于内核的部分(影响性能)
微内核 某些服务需要 设计 进程和存储管理的时候就会多次切换用户态和内核态、所以可能会影响性能
-
分层结构:内核分多层 每层单项调用更低一层的接口
- 便于调试验证、拓展、维护(确保每层都对就对)
- 效率低不能跨层调用
例如最外层只需要最底层的某个功能只能一层层的去调用
-
模块化:内核分模块 = 主内核 + 可加载内核
- 主内核:只有核心功能(进程调度、内存管理)
- 动态加载需要的内核而不是之前把全部都放上
- 模块内的逻辑更清晰、支持添加新内核、模块间互相调用效率高
- 模块的接口不一定合理使用、不好调试
-
大内核(宏内核):所有系统功能全放在内核(有模块思想)
- 性能高
- 不易维护、某一个模块出问题集体崩溃
-
微内核:只把核心功能放在内核
- 可靠、容易维护、内核外崩了不影响
- 性能不好、用户态下交流消息要通过内核
-
外核(exokernel):内核负责进程调度通信、外核负责给进程分配硬件资源且需要保证安全的使用硬件资源
- 用户进程能灵活使用硬件资源、减少了硬件映射层提高效率
- 因为灵活就像是c语言的指针灵活但是会让项目变得复杂,它会让系统变得复杂
开机过程
CPU RAM 磁盘引导程序加载到这里 =》
操作系统加载到这里 断电没有了
ROM (BIOS) 断电了也还有
虚拟机
两个应用在同一个操作系统运行可能有问题
解决方法第一个是再找个物理机
但是这样会浪费
所以直接让一个物理机运行两个操作系统
两类:
- 直接运行在硬件上面、物理机器虚拟化多台
- 运行在宿主操作系统上
第二章节进程和线程管理
程序是静态的,就是个存放在磁盘的可执行文件
系统在管理这些进程并发执行的时候需要的信息都会放在 PCB 这个模块中 进程控制块
进程的组成 程序段、数据段、PCB
Windows UNIX Linux Mac 都是支持多任务的操作系统
进程:就是一个程序运行在操作系统之上,程序运行起来就是一个运行的进程,并且分配 ID 方便管理。
线程:线程属于进程,一个进程能开启多个线程去执行不同的工作,是进程的实际工作最小单位(进程实际工作的工作者)。
进程本质上是一堆线程的集合
操作系统能运行多个进程,多任务运行。
一个进程内有可以运行多个线程,即多线程运行。
注意:
- 操作系统上进程之间的内存是隔离的,就是不同的进程各自有各自的内存空间。
- 正常软件运行出的进程是不能访问其他进程的内存的
- 一个进程内的线程之间内存是共享的
并行执行:同一时间做不同的工作,
进程之间就是在并行执行的,操作系统可以同时运行多个程序,这些程序都是在并行执行
线程也是可以并行执行的,比如写个 python 程序
一个线程输出:hello
一个线程输出:world
像是这样一个程序在同一时间做两件乃至多件不同的事情,
就称之为多线程并行执行
进程和程序的区别
- 程序是永存的;进程是暂时的,是程序在数据集上的一次执行,有创建有撤销,存在是暂时的;
- 程序是静态的观念,进程是动态的观念;
- 进程具有并发性,而程序没有;
- 进程是竞争计算机资源的基本单位,程序不是。
- 进程和程序不是一一对应的:一个程序可对应多个进程即多个进程可执行同一程序;一个进程可以执行一个或几个程序
进程的三状态模型和五状态模型
运行 就绪 阻塞 + 创建 和 终止态
进程控制
为什么要使用原语进行?
例如:阻塞态转换为就绪
阻塞队列中的 1. PCB 指针 state 更改
2. 从阻塞队列到就绪队列
至少要完成两步且都要完成不能中断所以需要原语
原语怎么实现:关中断指令和开中断指令两个特权指令
进程结束:正常结束、异常结束、用户手动
进程之间的通信
三种通信方式 共享存储 消息传递 管道通信
-
共享内存(高级 速度快)
顾名思义,共享内存就是两个进程同时共享一块内存,然后在这块内存上的数据可以共同修改和读取,达到通信的目的。
-
消息传递的方式去进行:
分为- 直接通信 直接发送原语实现 指明发给 PID = 909
- 间接通信 邮箱中间体实现
进程的 PCB 包含一个消息队列
2.1 直接通信就是 A 指名发给 B (发送原语)
消息到 B 的 PCB 消息队列中
B 指名要 A 的消息(接收原语)
从 PCB 消息队列中检查
2.2 间接通信就是 AB 通过邮箱实体去通信
A 指名发给邮箱 1
B 指名要邮箱已 1 的消息
-
管道通信
半双工通信
A 写数据 =》 单向管道 =》 读数据 B
各个进程对于管道的访问也是互斥的进行
管道中写满了 写进程将会阻塞
管道中读空了 读进程阻塞
线程
线程是操作系统能够进行运算调度的最小单位
没有引入进程概念之前,程序只能串行执行
引入线程后,操作系统中能拥有资源和独立运行的单位是进程
但是早期的进程只能串行的执行一系列程序
所以引入了线程,来增加并发度,就是为了进程能同时做很多事情线程成为了程序执行的最小单位,线程可以理解成轻量级的进程
线程成为了基本的 CPU 执行单元
各个线程之间也可以并发,提高了系统的并发度
进程和线程的区别
- 进程(Process)是系统进行资源分配和调度的基本单位,
线程(Thread)是 CPU 调度和分派的基本单位; - 线程依赖于进程而存在,一个进程至少有一个线程;
- 进程有自己的独立地址空间,线程共享所属进程的地址空间;
- 进程是拥有系统资源的一个独立单位,而线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),和其他线程共享本进程的相关资源如内存、I/O、cpu 等;
- 在进程切换时,涉及到整个当前进程 CPU 环境的保存环境的设置以及新被调度运行的 CPU 环境的设置,
而线程切换只需保存和设置少量的寄存器的内容,并不涉及存储器管理方面的操作,
进程切换的开销远大于线程切换的开销;线程之间的通信更方便,同一进程下的线程共享全局变量等数据,而进程之间的通信需要以进程间通信(IPC)的方式进行; - 多线程程序只要有一个线程崩溃,整个程序就崩溃了,
但多进程程序中一个进程崩溃并不会对其它进程造成影响,
因为进程有自己的独立地址空间,因此多进程更加健壮
用户级线程ULT与内核级线程
用户级线程ULT:
应用程序通过线程库来实现的,用户能感知到操作系统感知不到
优点:不涉及 CPU 用户态和核心态切换,开销小,效率高
缺点:如果某个阻塞了,整个程序都阻塞
内核级线程:
- 管理工作由操作系统来管理
- 线程切换需要 CPU 变态
优点:一个线程阻塞,不影响其他线程的执行
缺点:切换时开销大、效率低
进程调度算法
调度:一队任务要处理时先处理谁的规则
调度分三个层次–高级调度–低级调度
-
作业调度–高级–低级–中级
作业的概念:一个具体的任务
比如 我让操作系统启动一个程序
每个作业在生命周期内只调入一次,调出一次,调入时会创建 PCB,调出```markdown
撤销 PCB -
进程调度–低级
从就绪队列选取进程,分配处理机
-
内存调度–中级
内存不足,程序无法进入内存就绪,挂起的进程组成队列
现在有内存了,调度某个进程放入内存中
进程调度算法
进程调度是低级调度
什么时候需要进程调度?
答:需要进行调度的时有两种情况
- 当前进程主动放弃处理机
- (1) 正常终止
- (2) 发生异常
- (3) 主动请求阻塞(如等待 IO)
- 当前进程被动放弃
- (1) 分配的时间片用完
- (2) 有更紧急的进程要处理
- (3) 优先级更高的进程进入
什么时候不能进程调度?
答:
- 在处理中断过程中不可进行。
- 进程在操作系统内核程序临界区内
- 原语操作
狭义的调度与切换区别?
答:狭义的进程调度就是在就绪队列中选择要运行的进程。
广义的进程调度包含选择运行进程和进程切换。
(这个进程可以是刚刚被暂停的进程,也可以是另一个进程,如果是另一个进程,就需要进程切换)
进程切换是一个进程让出处理机,另一个进程占用处理机
一般包含 - 对原来运行进程数据的保存
- 对新进程各种数据的恢复
什么时候会触发调度程序?
答: - 就绪序列进入新进程(抢占式调度,新进入的很紧急)
- 当前进程退出
- 运行的进程阻塞
进程调度算法有两种都是什么?
答:分为非抢占(非剥夺)式和抢占(剥夺)式两种
非抢占式只允许进程主动放弃处理机
抢占式允许主动放弃和被动放弃处理机
调度算法通过 CPU 利用率来决定好坏:忙碌/总时间
调度算法通过系统吞吐量来决定好坏:总作业数目/总时间
调度算法通过平均周转时间决定好坏:总周转时间/作业数
调度算法通过带权周转时间决定好坏:等待时间/运行时间
调度算法平均带权周转时间决定好坏:总带权周转/作业数
响应时间:用户提交请求到首次响应的时间
进程调度算法列表
- 先来先服务 FCFS
算法思想:公平角度出发 类似排队
规则:按照到达顺序进行服务
作业/进程:作业考虑后备队列、进程考虑谁先到就绪队列
抢占?:非抢占
优点:对时间长进程有利
缺点:不能处理紧急时间,对短进程不利
饥饿:不饥饿 - 最短作业优先 SJF
算法思想:追求少的平均等待时间
规则:服务时间短的进程优先得到服务
作业/进程:两者都行
抢占?:非抢占
优点:短时间进程有利、平均等待时间和平均周转时间短
缺点:短作业有利长作业不利,可能饥饿
饥饿:饥饿 - 最短剩余时间优先(抢占式)
算法思想:追求少的平均等待时间
规则:剩余时间短的进程优先得到服务
作业/进程:进程中叫做“短进程优先”
抢占?:抢占
优点:平均等待时间和平均周转时间短
缺点:短作业有利长作业不利,可能饥饿
饥饿:饥饿 - 高响应比优先算法 HRRN
算法思想:考虑进程等待时间和要求服务时间
规则:响应比 = 1 + 等待时间/要求服务时间
最高的响应比优先级最高
抢占?:非抢占
优点:综合考虑了等待时间和运行时间,等待时间相同短作业优先,服务时间相同,等待时间长优先。而且还可以避长进程的饥饿问题。
饥饿:不饥饿 - 时间片轮转算法 RR
算法思想:公平、轮流为各个进程服务
规则:每个进程都执行规定的时间,时间内结束主动退出让下一个进入,超时强制退出到就绪队列队尾
抢占?:抢占
优点:公平响应快、适用分时系统
缺点:进程切换频繁,不区分任务紧急程度
饥饿:不饥饿 - 优先级调度算法
算法思想:越来越多场景,需要根据任务紧急程度,
来决定处理的顺序
规则:调度时选择优先级最高者
抢占?:抢占 非抢占都有
优点:优先处理紧急的进程、灵活
缺点:可能导致饥饿
饥饿:饥饿
优先级算法分静态优先级和动态优先级
通常系统进程的优先级高于用户优先级
IO 频繁 的进程优先级更高,这样会提高效率 - 多级反馈队列调度算法 RR
算法思想:其他调度算法的折中
规则:设置多个就绪队列 1、2、3…,优先级递减,时间片递增。只有等到优先级更高的队列为空时才会调度当前队列中的进程。新进程进入先到第一级队列,如果进程用完了当前队列的时间片还未执行完,则会被移到下一队列。抢占式(时间片用完时),开销可能较大,对 IO 型进程有利,可能会出现饥饿问题(新的短进程源源不断到第一队列)。
进程同步和互斥是操作系统中确保多个进程能够正确、有效地共享资源的机制。以下是一些常见的进程同步和互斥方法的概述:
进程同步互斥原则:
- 空则让进:如果资源未被占用(即为空),则允许请求进程进入临界区。
- 忙则等待:如果资源正被占用,则请求进程必须等待直到资源变为可用状态。
- 有限等待:确保所有等待资源的进程在有限的时间内能得到服务,避免饥饿现象。
- 让权力等待(等待时释放CPU):当进程等待资源时,应释放CPU,以避免浪费系统资源。
异步与同步的特征:
- 异步:并发执行的进程以独立的速度向前推进,不等待其他进程的结果。这使得进程的当前进度不可预测。
- 同步:任务提交后,进程会阻塞,原地等待任务完成并返回结果。在等待期间,进程不进行其他操作。
进程互斥:
确保在同一时刻只有一个进程能进入临界区,以防止数据不一致和资源冲突。
如何实现互斥访问:
-
单标志法:
- 使用一个标志来控制对临界区的访问。
- 标志通常表示进程号,表明哪个进程拥有访问权。
- 缺点:如果拥有标志的进程阻塞或崩溃,其他进程可能永远无法进入临界区,违反了“空则让进”的原则。
-
双标志法:
- 使用布尔数组
flag
【】来表示每个进程是否想要进入临界区。 - 进程在进入临界区前检查其他进程的
flag
【j】状态。 - 如果其他进程也想进入临界区,则等待;否则,设置自己的
flag
[i]为true
并进入临界区。 - 使用完毕后,将
flag
[i]设置为false
。 - 缺点:如果两个进程同时检查并发现对方不想要进入临界区,它们可能同时进入临界区,违反了忙则等待。
- 使用布尔数组
后检查方法:
- 一种改进的互斥方法,它在进程执行到临界区之前进行后检查,以确保不会发生冲突。
- 这种方法可能会违反“忙则等待”和“有限等待”的原则,因为它允许进程在临界区外循环检查,可能导致饥饿问题。
为了解决这些问题,操作系统提供了多种同步机制,如信号量、互斥锁和条件变量等,它们能够更有效地管理进程间的同步和互斥。这些机制确保了资源共享的安全性,同时提高了系统的效率和响应性。