操作系统
1.1_1 操作系统的概念、功能和目标
作为用户和计算机硬件之间的接口
-
提供的功能
-
命令接口(联机命令接口|脱机命令接口)
-
程序接口
-
GUI(图形用户界面win|ios|andrio)
-
-
目标
- 方便用户使用
1.1_2 操作系统的特征
并发|并行
并发:多个事件交替发生(宏观同时发生、微观交替进行)
并行:多个事件同时发生
共享
两种资源共享方式
- 互斥共享方式:一个时间段内只允许一个进程访问该资源
- 同时共享方式:允许一个时间段内由多个进程“同时”对它们进行访问
虚拟
概念:把一个物理上的实体变为若干个逻辑上的对应物
- 空分复用计数
- 时分复用计数
异步
概念:在多道程序环境下,允许多个程序并发执行,但由于资源有限,进程的执行不是一贯到底的,而是走走停停的,以不可预知的速度向前推进。只有系统拥有并发性,才有可能导致异步性。
1.1_3 操作系统的发展与分类
OS的发展与分类
- 手工操作阶段
- 纸带机(用户独占全机、人机速度矛盾)
- 批处理阶段——dan’dao
- 单道批处理系统(外围机——磁带)
- 多道批处理系统(操作系统开始出现)
- 分时操作系统
- 轮流处理作业
- 不能处理紧急任务
- 实时操作系统
- 优先处理紧急任务
- 硬实时系统:必须在严格的时间内完成处理
- 软实时系统:可以偶尔犯错
- 网络操作系统
- 分布式操作系统
- 个人计算机操作系统
1.1_4 操作系统的运行机制与体系结构
OS的运行机制和体系结构
- 运行机制
- 两种指令
- 特权指令
- 非特权指令
- 两种处理器状态
- 核心态(root)
- 用户态
- 两种程序
- 内核程序(运行在核心态 )
- 应用程序
- 两种指令
- 操作系统内核
- 时钟管理(实现计时功能)
- 中断处理
- 原语(程序运行具有原子性,不可中断)
- 对系统资源进行管理的功能
- 进程管理
- 存储器管理
- 设备管理
- 操作系统的体系结构
- 大内核(将操作系统的主要功能模块都作为系统内核,运行在核心态)
- 微内核(只把最基本的功能保留在内核)
1.1_5 中断和异常
- 中断机制的诞生
- 操作系统介入,开展管理工作
- “用户态—>核心态”是通过中断实现的。并且中断是唯一途径
- 中断的概念和作用
- 中断的分类
- 内中断(异常)
- 陷阱(trap)
- 故障(fault)
- 中止(abort)
- 外中断 (CPU外部)
- 内中断(异常)
- 外中断的处理过程
1.1_6 系统调用
概念:应用程序通过系统调用请求操作系统的服务。保证系统的稳定性和安全性。
系统调用和库函数的区别:
- 系统调用是操作系统向上层提供的接口
- 有的库函数是对系统调用的进一步封装
- 当今编写的应用程序大多是通过高级语言提供的库函数间接地进行系统调用
2.1_1 进程的定义、组成、组织方式、特征
定义:
组成:PCB(进程存在唯一的标志),程序段,数据段
组织方式:链接方式,指针指向不同的队列;索引方式,索引表
特征:动态性、并发性、独立性、异步性、结构性
2.1_2 进程的状态与转换
状态:
运行状态:占有CPU,并在CPU上运行,单核只能一个进程(双核两个)(CPU√,其它资源√)
就绪状态:已经具备运行条件,但是没有空闲的CPU,暂时不能运行(CPUX,其它资源√)
阻塞状态:等在某个事件的发生,暂时不能运行(CPUX,其它资源X)
创建状态:创建PCB,程序段,数据段
终止状态:回收内存,程序段,数据段,撤销PCB
进程状态间的转换(图,且只能这样转化)
创建态->就绪态
就绪态->运行态
运行态->就绪态
运行态->中止态(比如数组越界)
运行态->阻塞态(主动)
阻塞态->就绪态(被动)
2.1_3 进程控制
基本概念:
什么是进程控制?
答:实现各种进程状态转换。
如何实现进程控制?
答:用“原语”实现。
原语做的事情:
1、更新PCD中的信息
2、将PCD插入合适的队列
3、分配/回收资源
进程控制相关的原语:
1、进程的创建:
创建原语:申请空白PCB、为新进程分配所需资源、初始化PCB、将PCB插入就绪队列
引起进程创建的事件:用户登录、作业调度、提供服务、应用请求
2、进程的终止:
撤销原语
引起进程中止的事件:正常结束、异常结束、外界干预
3、进程的阻塞:
阻塞原语:运行态->阻塞态
引起进程阻塞的事件:需要等待系统分配某种资源、需要等待相互合作的其他进程完成工作
4、进程的唤醒:
唤醒原语:阻塞态->就绪态
引起进程唤醒的事件:等待的事件发生
5、进程的切换
切换原语
引起进程切换的事件:当前进程事件片到、有更高优先级的进程到达、当前进程主动阻塞、当前进程终止
2.1_4 进程通信
1、共享存储 (分配共享空间,且互斥(P、V操作)
基于数据结构的共享:固定分配(低级)
基于存储区的共享:划分存储区(高级)
2、消息传递
消息:消息头、消息体
直接通信方式(直接挂载消息)
间接通信方式(间接利用信箱发送消息)
3、管道通信(pipe)
只能半双工通信
互斥(没写满,不能读,反之同理)
2.1_5 线程概念和多线程模型
什么是线程,为什么要引入线程?
答:线程是一个基本的CPU执行单元,也是程序执行流的最小单位,进一步提高了系统的并发度
引入线程机制后,有什么变化?
资源分配、调度:进程是资源分配的基本单位,线程是调度的基本单位
并发性:各线程间也能并发,提升了并发度
系统开销:可以只在进程中切换,减小了CPU切换环境的系统开销
1、线程有哪些重要的属性
- 线程是处理机调度的基本单位
- 多CPU计算机中,各个线程可占用不同的CPU
- 每个线程都有一个线程ID、线程控制块(TCB)
- 线程也有就绪、阻塞、运行三种基本状态
- 线程几乎不拥有系统资源
- 同一进程的不同线程间共享进程的资源
- 由于共享内存地址空间,统一进程中的线程间通信甚至无需系统干预
- 同一进程中的线程切换,不会引起进程切换
- 不同进程中的线程切换,会引起进程切换
- 切换同进程内的线程,系统开销很小
- 切换进程,系统开销较大
2、线程的实现方式
用户级线程(ULT):
由应用管理,从用户的视角看能看到的线程
内核级线程(KLT):
由操作系统管理,从操作系统内核视角看能看到的线程
n个ULT可以映射到m个KLT上(n>=m)
内核级线程才是处理机分配的单位
3、多线程模型
多对一模型
n个ULT映射到1个KLT
优点:开销小,效率高
缺点:容易阻塞,并发度不高
一对一模型
n个ULT映射到n个KLT
优点:并发能力很强
缺点:占用成本高,开销大
多对多模型
n个ULT映射到m个KLT上(n>=m)
中和以上两种优缺点
2.2_1 处理机调度的概念、层次
基本概念
通常进程数量大于处理机数量,所以要按照一定的算法选择一个进程,并将处理机分配给它运行,以实现进程的并发执行
三个层次
高级调度(作业调度)
辅助外存与内存之间的调度,作业调入时会建立相应的PCB,作业调出时才撤销PCB,调入可由操作系统决定,调出由作业运行结束才调出
中级调度(内存调度)
将暂时不用的进程放到外存(PCB不外放),提高内存利用率和系统吞吐量,进程状态为挂起状态,形成挂起队列
低级调度(进程调度)
最基本,用算法为进程分配处理机资源,几十ms一次
三层调度的联系、对比
进程的“挂起态”
七状态模型
五状态前面学了,挂起分为就绪挂起、阻塞挂起
2.2_2 进程调度的时机、切换与过程调度方式
1、时机
什么时候需要进程调度?
- 主动放弃(进程正常终止、运行过程中发生异常而终止、进程主动请求阻塞)
- 被动放弃(分给进程的时间片用完、有更紧急的事需要处理、有更高优先级的进程进入就绪队列)
什么时候不能进行进程调度?
- 在处理中断的过程中
- 在操作系统内核程序临界区中
- 临界资源:一个时段段内各进程互斥地访问临界资源
- 临界区:访问临界资源的那段代码
- 内核程序临界区会访问就绪队列,导致其上锁
- 在原子操作过程中(原语)
2、切换与过程
“狭义的调度”与“进程切换”的区别
- 狭义:选择一个进程
- 广义:狭义+进程切换
进程切换的过程需要做什么?
- 对原来运行进程各种数据的保存
- 对新的进程各种数据的恢复
3、方式
非剥夺调度方式(非抢占式)
- 只允许进程主动放弃处理机
剥夺调度方式(抢占式)
- 进程被动放弃,可以优先处理紧急任务,适合分时操作系统、实时操作系统
2.2_3 调度算法的评价指标
1、CPU利用率
CPU利用率=CPU忙碌的时间/总时间
2、系统吞吐量
=总共完成了多少道作业/总共花费了多少时间
3、周转时间
- 纯计算型:周转时间 =运行时间+等待时间 / 完成时间-到达时间
- 有IO操作的进程:周转时间 =运行时间+等待时间+IO操作时间
- 周转时间(提交作业到完成作业花费的时间)、平均周转时间(各作业周转时间之和/作业数)
- 带权周转时间**(作业周转时间/作业实际运行的时间)**、平均带权周转时间(各作业带权周转时间/作业数)
4、等待时间
- 等待时间=开始调度时间-到达时间 / 周转时间-运行时间
进程或作业等待处理机状态时间的和
进程:等待被服务的时间之和
作业:建立后的等待时间+作业在外存后备队列中等待的时间
5、响应时间
从用户提交请求到首次产生响应所用的时间
2.2_4 FCFS、SJF、HRRN调度算法
1、先来先服务(FCFS)
先到达先进行服务
作业-后备队列;进程-就绪队列
非抢占式
优点:公平、算法简单
对长作业有利、对短作业不利、不会饥饿
2、短作业优先(SJF,shortest Job first)
进程调度时:SPF(Shortest Process First)
最短(运行时间最短)的作业优先得到服务,时间相同,先到达的先被服务
非抢占式(SJF):选最短需要时间的作业先进入运行态
抢占式(SRTN):默认就是非抢占 有新作业进入就绪队列或有作业完成了,考察队列中的最小需要时间的作业
在所有进程都几乎同时到达时,采用SJF调度算法的平均等待时间、平均周转时间最少
若无红色前提,抢占式的短作业/进程的平均时间最少
优点:“最短的”平均等待时间,平均周转时间
缺点:对短作业有利,对长作业不利,可能产生 饥饿现象(一直来更短时间的作业)
3、高响应比优先(HRRN)
要综合考虑作业/进程的等待时间和要求服务的时间
在每次调度时先计算各个作业/进程的响应比,选择响应比最高的作业/进程为其服务
响应比=(等待时间+要求服务时间) / 要求服务时间 响应比越高 先服务
每进行一个进程 都要重新计算 响应比
非抢占式
进程主动放弃CPU时,需要该算法选取就 绪队列的作业
不会饥饿
2.2_5 时间片轮转、优先级调度、多级反馈队列(适合交互式系统)
1、时间片轮转算法(RR)
算法思想:公平轮流地位各个进程服务,让每个进程在一定时间间隔内都可以得到响应
算法规则:按照各进程到达就绪队列的顺序,轮流让各个进程执行一个时间片(如100ms)。若进程未在一个时间片内执行完,则剥夺处理机,将进程重新放到就绪队列对位重新排队。
只能用于进程调度
抢占式
优点:响应块,适用于分时操作系统
缺点:由于高频率的进程切换,因此有一定的开销;不区分任务的紧急程度
不会饥饿
2、优先级调度算法
算法思想:根据任务的紧急程度来决定处理顺序
算法规则:每个进程/作业有各自的优先级,调度时选择优先级最高的作业/进程
适用:作业/进程/IO
抢占式/不可抢占均有
静态优先级:不变
动态优先级:可以变
通常:系统进程优先级高于用户进程,前台进程优先级高于后台进程,操作系统更偏好I/O进程
可以从追求公平、提升资源利用率等角度考虑改变优先级
可能会饥饿
3、多级反馈队列调度算法
UNIX
算法思想:对其它算法调度的这种权衡
算法实现:设置多级就绪队列,各级队列优先级从高到低,时间片从小到大。新进程到达时先进入第一级队列,按照FCFS原则排队等待被分配时间片。若用完时间片进程还未结束,则进程进入下一级队列对位。如果此时已经在最下级的队列,则重新放回最下级队列末尾。啊只有第K级队头的进程为空时,才会为K+1级对头的进程分配时间片,被抢占处理机的进程重新放回原队列队尾。
优点:对各个进程相对公平(FCFS的优点),每个新到达的进程都可以很快就得到响应(RR的优点);短进程只用较少的时间就可以完成(SPF的优点);不必实现估计进程的运行时间(避免用户作假);可灵活地调整对各类进程的偏好程度,比如CPU密集型进程、IO密集型进程
默认抢占式
会饥饿
2.3_1 进程同步、进程互斥
1、进程同步
指为了完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调他们的工作次序而产生的制约关系。进程间的直接制约关系就是源于它们之间的相互合作。
2、进程互斥
把一个时间段内只允许一个进程使用的资源称为临界资源。
对临界资源的互斥访问,可以在逻辑上分为四个部分:
do{
entry section; //进入区 对访问的资源检查或进行上锁
critical section; //临界区(段) 访问临界资源的那部分代码
exit section; //退出区 负责解锁
remainder section; //剩余区 其它处理
} while(true)
1、空闲让进。 空的可以直接进去
2、忙则等待。 繁忙不能进去
3、有限等待。 不能让进程等待无限长时间
4、让权等待。 不能进去,不要堵着
2.3_2 进程互斥的软件实现方法
1、单标志法
两个进程在访问完临界区后会把使用临界区的权限教给另一个进程。也就是说每个进程进入临界区的权限只能被另一个进程赋予
int turn =0;
//p0进程
while(turn!=0);
critical section;
turn = 1;
remainder section;
//p1进程
while(turn!=1);
critical section;
turn = 0;
remainder section;
可以实现互斥
存在的问题:p1要访问的话,必须p0先访问,违背:空闲让进原则
2、双标志先检查
算法思想:设置一个bool数组flag[]来标记自己是否想要进入临界区的意愿
bool flag[2]={
false,false};
//p1进程
while(flag[1]);
flag[0]=true;
critical section;
flag[0]=false;
remainder section;
//p2进程
while(flag[0]);
flag[0]=true;
critical section;
flag[1]=false;
remainder section;
主要问题:由于进程是并发进行的,可能会违背忙则等待的原则
3、双标志后检查
算法思想:设置一个bool数组flag[]来标记自己是否想要进入临界区的意愿,不过是先上锁后检查
bool flag[2]={
false,false};
//p1进程
flag[0]=true;
while(flag[1]);
critical section;
flag[0]=false;
remainder section;
//p2进程
flag[0]=true;
while(flag[0