操作系统OS
操作系统
定义
操作系统是指控制和管理整个计算机系统的硬件和软件资源,并合理地组织调度计算机的工作和资源的分配;以提供给用户和其他软件方便的接口和环境;它是计算机系统中最基本的系统软件。
联机命令接口:用户输入一条指令,操作系统执行一条指令,接着用户输入一条指令,操作系统执行一条指令,循环如此
脱机命令接口:用户输入一堆指令,操作系统执行一堆指令,接着用户输入一堆指令,操作系统执行一堆指令,循环如此
特征
- 并发
指两个或多个事件在同一时间间隔内发生。这些事件宏观上是同时发生的,微观上是交替发生的
并行:指两个或多个事件在同一时刻同时发生。
- 共享
即资源共享,是指系统中的资源可供内存中多个并发执行的进程共同使用。
共享方式分为两种:互斥共享方式、同时共享方式
互斥共享方式指系统中的某些资源,虽然可以提供给多个进程使用,但一个时间段内只允许一个进程访问该资源
同时共享方式:允许一个时间段内由多个进程“同时”对它们进行访问
- 虚拟
是指把一个物理上的实体变成若干个逻辑上的对应物。物理实体是实际存在的,逻辑对应物是用户感受到的。
虚拟技术分为:空分复用技术、时分复用技术
空分复用技术:比如我的电脑只有4GB内存,但却运行了一个200GB的游戏
时分复用技术:单核CPU的电脑同时运行着多个应用程序
- 异步
是指,在多道程序环境下,允许多个程序并发执行,但由于资源有限,进程的执行不是一贯到底的,而是走走停停,以不可预知的速度向前推进。
其中,并发和共享是最基本的特征。
发展与分类
操作系统的运行机制
应用程序:普通程序员写的程序
内核程序:开发操作系统的程序员开发的程序,由很多内核程序组成了“操作系统内核”,简称“内核(Kernel)”。内核是操作系统最重要最核心的部分,也是最接近硬件的部分。
特权指令:操作系统内核作为“管理者”,有时会让CPU执行一些“特权指令”,如:内存清零指令。这些指令影响重大,只允许“管理者”来使用。
非特权指令:例如加法、减法指令等
CPU能判断出指令类型,但是它如何区分此时正在运行的是内核程序还是应用程序呢?
CPU有两种状态:内核态和用户态,处于内核态时,说明此时正在运行的是内核程序,可以执行特权指令。处于用户态时,说明此时正在执行的是应用程序,此时只能执行非特权指令。
CPU中有一个寄存器(程序状态字寄存器PSW),有个二进制位,1表示内核态,0表示用户态。
内核态也叫核心态、管态,用户态也叫目态。
内核态与用户态的切换
内核态到用户态:执行一条特权指令,修改PSW标志位,让出CPU使用权
用户态到内核态:由中断引发,硬件自动完成变态过程,触发中断信号意味着操作系统强行夺回CPU的使用权。
如果系统此时处于用户态,但是应用程序中运行了一个特权指令(特权指令只能在内核态执行),CPU会检测出来并拒绝执行这条特权指令,同时会引发一个中断信号。中断使得操作系统再次夺回CPU的控制权,操作系统会对引发中断的事件进行处理,处理完了再把CPU使用权交给别的应用程序。
中断和异常
内中断:与当前指令有关,中断信号来自CPU内部。
例如:
1、在用户态执行特权指令,CPU检测到以后就会触发中断,切换回内核态,夺取CPU控制权,拒绝执行这个指令,转而去执行中断对应的应用程序
2、执行除法除数为0的指令
3、应用程序想要请求操作系统内核的服务,此时会执行一条特殊的指令–陷入指令,该指令会引发一个内部中断信号
外中断:与当前指令无关,中断信号来自CPU外部。每一条指令执行结束后,CPU都会检查是否有外中断信号
例如:
1、由时钟信号发来的中断信号,时钟部件每隔一段时间给CPU发送一个时钟中断信号
2、IO中断:由输入输出设备发出的中断信号
系统调用
操作系统的体系结构
进程
进程的概念
进程是系统进行资源分配和调度的一个独立单位。PCB是进程存在的唯一标志。
进程的状态及转换
进程控制
执行了关中断之后,即使出现中断信号,CPU也不会去处理中断,而是继续往下执行。等到执行到开中断,如果出现中断信号,才开始处理中断。这就保证了原子操作。
进程通信
进程间通信是指两个进程之间产生数据交互。
共享存储
每个进程都有自己独立的内存空间,进程只能访问自己的内存空间,无法访问其他进程的内存空间。共享存储是申请一个共享存储区,使得多个进程可以共同访问这片区域。需要注意的是,多个进程同时对共享存储区的访问应该是互斥的,不然就会出现问题,例如写入覆盖。
线程
线程的概念
线程是一个基本的CPU执行单元,也是程序执行流的最小单位。
线程的实现方式和多线程模型
线程的状态和转换
调度
调度的概念
当有多个任务需要处理,但由于资源有限,这些任务没法同时处理,这就需要确定某种规则来决定处理这些任务的顺序,这就是调度。
进程调度的时机、过程与方式
进程调度(低级调度),就是按照某种算法从就绪队列中选择一个进程为其分配处理机。
临界资源:一个时间段内只允许一个进程使用的资源,各进程需要互斥地访问临界资源。
临界区:访问临界资源的那段代码。
进程调度方式:非剥夺方式(非抢占方式)、剥夺方式(抢占方式)
非剥夺方式:只允许进程主动放弃处理机,在运行过程中即便有更紧迫的任务到达,当前进程依然会继续使用处理机,直到该进程终止或主动要求进入阻塞态。
剥夺方式:当一个进程正在处理机上执行时,如果有一个更重要的进程需要使用处理机,则立即暂停正在执行的进程,将处理机分配给更重要的那个进程。
调度算法的评价指标
调度算法
先来先服务FCFS
按照作业或进程到达的先后顺序进行服务。非抢占式
优点:公平、算法简单
缺点:排在长作业后面的短作业需要等待很长时机,FCFS对长作业有利,对短作业不利。
不会导致进程饥饿(饥饿指进程长期得不到服务)
短作业优先SJF
最短的作业或进程优先得到服务,最短即要求服务时间最短。默认是非抢占式,也有抢占式的算法,即最短剩余时间优先SRTN
优点:“最短的”平均等待时间、平均周转时间
缺点:不公平,对短作业有利,对长作业不利,可能产生进程饥饿。如果源源不断地有短作业到了,就会导致长作业长时间得不到服务,产生饥饿现象。
最短剩余时间优先
和短作业优先相比,最短剩余时间优先增加了CPU抢占的功能,当前运行的任务与新来的任务,哪个运行时间段就执行哪个。
高相应比优先HRRN
在每次调度时先计算各个作业的响应比,选择响应比最高的作业为其服务。非抢占式
响应比=(等待时间+运行时间)/ 运行时间
等待时间相同时,运行时间短的优先,有利于短作业;运行时间相同时,等待时间长的优先,类似于先来先服务。不会导致饥饿。
上述三种算法在早期的批处理系统中使用,现在的系统中使用较少。
时间片轮转调度算法RR
按照各进程到达就绪队列的顺序,轮流让各个进程执行一个时间片,若进程未在一个时间片内执行完则剥夺处理机,将进程重新放到就绪队列队尾重新排队。不会导致作业饥饿。
若进程未能在时间片内运行完成,就会被剥夺处理机,这种算法属于抢占式算法。
优点:公平,响应快,适用于分时操作系统
缺点:进程切换有一段的开销,不区分任务的紧急程度
优先级调度算法
每个作业或进程各有自己的优先级,调度时选择优先级最高的。
抢占式、非抢占式都有。
优点:用优先级区分紧急程度,适用于实时操作系统。
缺点:若有源源不断的高优先级进程到来,则可能导致饥饿
多级反馈队列调度算法
1、设置多级就绪队列,各级队列优先级从高到低,时间片从小到达
2、新进程到达时,先进入第1级队列,按照FCFS原则排队等待分配时间片,若用完时间片进程还未运行结束,则进程进入下一级队列队尾。如果此时已经是最下级的队列,则重新放回该队列的队尾
3、只有第k级队列为空时,才会为k+1级队列的进程分配时间片。
属于抢占式算法
多级反馈队列综合了上述大多数算法的优点。可能会导致饥饿。
进程同步、进程互斥
进程互斥的软件实现方式
进程互斥的硬件实现方式
信号量机制
死锁
死锁的处理策略-预防死锁
死锁的处理策略-避免死锁
安全序列:指系统按照这种序列分配资源,则每个进程都能顺利完成。只要能找出一个安全序列,系统就是安全状态。当然,安全序列可能有多个。
如果分配了资源之后,系统中找不出任何一个安全序列,系统就进入了不安全状态。
如果系统处于安全状态,就一定不会发生死锁。如果系统进入不安全状态,就可能发生死锁
银行家算法
在资源分配之前,预先判断这次分配是否会导致系统进入不安全状态,以决定是否答应资源分配请求。
系统中有三种资源,总数是(10,5,7),某一时刻,5个进程P0-P4的最大资源需求和已分配资源如图,找出一个安全序列。
系统资源总数(10,5,7)减去已分配资源(7,2,5),剩余资源数为(3,3,2)
接着尝试给每一个进程进行分配。
1、给P0发现剩余资源无法满足。
2、给P1可以满足,于是尝试给P1分配资源,P1执行完成后释放自己占用的资源(2,0,0),此时系统中剩余资源为(5,3,2)。
3、给P0发现剩余资源无法满足。
4、给P2发现剩余资源无法满足。
5、给P3可以满足,于是尝试给P3分配资源,P3执行完成后释放自己占用的资源(2,1,1),此时系统中剩余资源为(7,4,3)。
6、给P0发现可以满足,P0执行完成后释放自己占用的资源(0,1,0),此时系统中剩余资源为(7,5,3)。
7、给P2发现可以满足,P2执行完成后释放自己占用的资源(3,0,2),此时系统中剩余资源为(10,5,5)。
8、给P4发现可以满足,P4执行完成后释放自己占用的资源(0,0,2),此时系统中剩余资源为(10,5,7)。
于是得到安全序列:P1、P3、P0、P2、P4,结果不唯一
死锁的处理策略-检测和解除
资源分配图
进程使用圆形表示,如上图有P1、P2两个进程。资源使用矩形表示,其中的小圆形表示资源的数量,即有3个R1资源,2个R2资源。
资源指向进行的箭头,表示资源已经分配给该进程,箭头的数量表示分配的资源数量;进程指向资源的箭头,表示进程请求资源,箭头数表示请求资源的数量。
如上图,我们先看资源分配。P1占用2个R1资源,P2占用1个R1资源和1个R2资源。现在P1是可以运行的,P2是不能运行的,因为P2需要2个R1资源。先让P1运行,运行完成之后释放掉相应的资源,就可以把与P1相关的连线都去掉,变成下图。
此时P2进行就可以运行了。P2运行完后归还系统资源,解除与之相连的边,就变成下图了。
按照上述步骤,最终能消除所有边,就称这个图是可以简化的,此时一定没有发生死锁。如果不能消除所有的边,就表明发生了死锁。
解除死锁
内存
动态分区分配算法
基本分页存储管理
局部性原理
分为时间局部性和空间局部性。
时间局部性:如果执行了程序中的某条指令,那么不久之后这条指令很有可能再次指向;如果某个数据被访问过,不久之后该数据很有可能再次被访问过(因为程序中存在大量的循环)
空间局部性:一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也很有可能被访问(因为很多数据在内存中都是连续存放的)。
基本分段存储管理
段页式管理方式
虚拟内存
请求分页管理方式
页面置换算法
页面的换入缓存需要磁盘IO,会有较大的开销,因此好的页面置换算法应该追求更少的缺页率
最佳置换算法OPT
每次选择淘汰的页面将是以后永不使用,或者在最长时间内不再被访问的页面。
按照顺序,第一个是7,没在内存块中发生一次缺页,此时内存块有空闲,于是将7放入内存块中;接下来是0,没在内存块中发生一次缺页,此时内存块有空闲,于是将0放入内存块中;接下来是1,没在内存块中发生一次缺页,此时内存块有空闲,于是将1放入内存块中;接下来是2,没在内存块中发生一次缺页,此时内存块没有空闲,需要进行页面置换。最佳置换算法是从当前节点往后,看内存块中哪个块后被访问到,于是将该块换出。这个例子中,内存块中的7在倒数第3次被访问到,而0、1在它之前,所以将7换出,2换入;接下来是0,在内存块中,不发生缺页。其他过程类似。
最佳置换算法可以保证最低的缺页率。但实际上,只有在进程执行过程组才能知道接下来会访问到的是哪个页面。操作系统无法提前预判页面访问序列。因此,最佳置换算法是无法实现的。
先进先出置换算法FIFO
每次淘汰的页面是最早进入内存的页面。
最近最久未使用置换算法LRU
每次淘汰的页面是最近最久未使用的页面。
LRU是逆向看,如图,在遇到3号页面不在内存块的场景,逆向查询会发现顺序是8、1、2、7,7号页面是最近最久未使用的页面,于是淘汰7号页面。
时钟置换算法CLOCK
改进型的时钟置换算法
页面分配策略
抖动:刚刚换出的页面马上又要换入内存,刚刚换入的页面马上又要缓存外存,这种频繁的页面调度行为称为抖动。
