计算机操作系统上

操作系统的概念(定义)

  • 操作系统是系统资源的管理者
  • 向上层提供方便易用的服务
  • 是最接近硬件的一层软件

作为系统资源的管理者

  • 执行一个程序之前需要将该程序放到内存中,才能被CPU处理

 第一步文件管理,第二步存储器管理,第三步处理机管理,第四步设备管理

向上层提供方便易用的服务 

操作系统把一些抽象的硬件功能封装成封装成简单易用的服务,使用户能更方便的使用计算机

 举例:GUI图形化用户接口:用户可以使用形象的图形界面进行操作,无需复杂的命令

 命令接口:用命令行的方式交互

  • 联机命令接口(交互式命令接口)
  • 命令窗(用户说一句,系统做一句)
  • 脱机命令接口(批处理命令接口)
  • .bat文件(用户说一堆,系统做一堆)

程序接口:在程序中进行系统调用来使用程序接口。普通用户不能直接使用,只能通过程序代码间接使用

 作为最接近硬件的层次

操作系统的四个特征 

并发 共享 虚拟 异步

并发 

  • 并发:指两个或多个事件(程序)在同一时间间隔内发生。宏观是同时发生。微观是交替发生的。(时间管理大师)
  • 并行:指两个或多个事件在同一时刻同时发生。(多p)
  • 操作系统和程序并发是一起诞生的
  • 单核CPU各个程序只能并发执行
  • 多核CPU多个程序可以并行执行(几核可以并行几个)

共享 

共享即资源共享,指系统中的资源公共内存中多个并发执行的进程共同使用

所谓的“同时”往往是宏观上的,而在微观上,这些进程可能是交替地对该资源进行访问的(即分时共享
生活实例:

  • 互斥共享方式:使用QQ和微信视频。同一时间段内摄像头只能分配给其中一个进程。
  • 同时共享方式:使用QQ发送文件A,同时使用微信发送文件B。宏观上看,两边都在同时读取并发送文件,说明两个进程都在访问硬盘资源,从中读取数据。微观上看,两个进程是交替着访问硬盘的。
并发和共享的关系 

 互为存在的条件

 虚拟

虚拟是指把一个物理上的实体变为若干个逻辑上的对应物。物理实体(前者)是实际存在的,而逻辑上对应物(后者)是用户感受到的。

 异步

异步是指,在多道程序环境下,允许多个程序并发执行,但由于资源有限,进程的执行不是一贯到底的,而是走走停停,以不可预知的速度向前推进,这就是进程的异步性。

 操作系统的发展和分类

手工操作阶段

用户独占全机,人机速度矛盾(人慢机快)导致资源利用率极低

单道批处理系统 

引入脱机输入/输出技术(用外围机和磁带完成),并有监督程序(操作系统的雏形)负责控制作业的输入输出(要处理的都先放到磁带,即处理工作先做好)

  • 主要优点:缓解了一定程度的人机速度矛盾,资源利用率有所提升。
  • 主要缺点:内存中仅能有一道程序运行,只有该程序运行结束之后才能调入下一道程序。CPU有大量的时间是在空闲等待I/0完成。资源利用率依然很低。

多道批处理系统

 每次往内存中读入多道程序,操作系统诞生,用于支持多道程序并发运行

 

分时操作系统 

计算机以时间片为单位轮流为各个用户/作业服务,各个用户可通过终端与计算机进行交互。

  • 主要优点:用户请求可以被即时响应,解决了人机交互的问题。运行多个用户使用一台计算机,并且用户对计算机的操作相互独立,干涉不到别人的存在。
  • 主要缺点:不能优先处理一些紧急任务。操作系统对各个用户/作业都是完全公平的,循环地为每个用户/作业服务一个时间片,不区分任务的紧急性。

实时操作系统

在实时操作系统的控制下,计算机系统接收到外部信号后及时进行处理,并且要在严格的时限内处理完事件。实时操作系统的主要特点是及时性和可靠性

  •  主要优点:能够优先响应一些紧急任务,某些紧急任务不需时间片排队。

操作系统的运行机制

  • 程序运行的过程其实就是CPU执行一条一条的机器指令的过程
  • “指令”就是处理器能识别、执行的最基本命令
  • 很多人习惯把 Linux、Windows、MacOs的“小黑框”中使用的命令也称为“指令”,其实这是“交互式命令接口”,注意与本节的“指令”区别开。本节中的“指令”指二进制机器指令

内核程序与应用程序

  • 应用程序:比如QQ什么的
  • 内核程序:包含操作系统中最重要,最内核的,最接近硬件的东西,内核程序组成了“操作系统内核”,简称“内核”
  • 操作系统所有的功能未必在内核中,如用户图像化界面GUI

内核态VS用户态

  • CPU有两种状态,“内核态”和“用户态”
  • 处于内核态时,说明此时正在运行的是内核程序,此时可以执行特权指令
  • 处于用户态时,说明此时正在运行的是应用程序,此时只能执行非特权指令
  • 拓展:CPÙ中有一个寄存器叫程序状态字寄存器(PSW),其中有个二进制位,1表示“内核态”,0表示“用户态
  • 别名:内存态=核心态=管态;用户态=目态

内存态、用户态的切换 

中断和异常 

 中断是让操作系统内核夺回CPU使用权的唯一途径

  • 引入中断技术的初衷是提高多道程序运行环境中CPU的利用率,而且主要是针对外部设备的。后来逐步得到发展,形成了多种类型,成为操作系统各项操作的基础
  • 例如,键盘或鼠标信息的输入、进程的管理和调度、系统功能的调用、设备驱动、文件访问等,无不依赖于中断机制。可以说,现代操作系统是靠中断驱动的软件。
  • 中断机制中,只有一小部分功能属于内核,它们负责保护和恢复中断现场的信息转移控制权到相关的处理程序。这样可以减少中断的处理时间,提高系统的并行处理能力。
  • 操作系统的发展过程大体上就是一个想方设法不断提高资源利用率的过程,而提高资源利用率就需要在程序并未使用某种资源时,把它对那种资源的占有权释放,而这一行为就需要通过中断实现。

 中断的类型

  • 内中断(也称异常、例外):与当前执行的指令有关,中断信号来源于CPU内部
  • 内中断例子:
    试图在用户态执行特权指令
    执行除法指令时除数为0(即指令非法)

异常可分为故障、自陷和终止。故障(Fault)通常是由指令执行引起的异常,如非法操作码、缺页故障、除数为0、运算溢出等。自陷(Trap)是一种事先安排的“异常”事件,用于在用户态下调用操作系统内核程序,如条件陷阱指令。终止(Abort)是指出现了使得CPU无法继续执行的硬件故障,如控制器出错、存储器校验错等。故障异常和自陷异常属于软件中断(程序性异常),终止异常和外部中断属于硬件中断

  • 外中断(也称“中断”):与当前执行的指令无关,终端信号来源于CPU外部
  • 外中断的例子:
  • 通常用于信息输入/输出,如设备发出的I/O结束中断,表示设备输入/输出处理已经完成。时钟中断,表示一个固定的时间片已到,让处理机处理计时、启动定时运行的任务等。
  • 时钟中断顺序:程序1->时间到->内核程序->程序2->时间到->内核程序->程序1(以此实现并发)

外中断可分为可屏蔽中断和不可屏蔽中断(所以内中断都是不可屏蔽中断)。可屏蔽中断是指通过INTR线发出的中断请求,通过改变屏蔽字可以实现多重中断,从而使得中断处理更加灵活。不可屏蔽中断是指通过NMI线发出的中断请求,通常是紧急的硬件故障,如电源掉电等。此外,异常也是不能被屏蔽的。

 

中断和异常处理过程的大致描述如下:当CPU在执行用户程序的第i条指令时检测到一个异常事件,或在执行第i条指令后发现一个中断请求信号,则 CPU打断当前的用户程序,然后转到相应的中断或异常处理程序去执行。若中断或异常处理程序能够解决相应的问题,则在中断或异常处理程序的最后,CPU通过执行中断或异常返回指令,回到被打断的用户程序的第i条指令或第i+1条指令继续执行(说明不都是恢复到i+1条指令,但是异常如缺页异常,自然就是恢复到第i条指令),若中断或异常处理程序发现是不可恢复的致命错误(所以说也有可能并不恢复到原来程序了,直接退出了),则终止用户程序。通常情况下,对中断和异常的具体处理过程由操作系统(和驱动程序)完成。

 系统调用

系统调用与库函数的区别 

系统调动的使用

所谓系统调用,是指用户在程序中通过系统调用请求操作系统的服务,系统调用可视为特殊的公共子程序。系统中的各种共享资源都由操作系统统一掌管,因此在用户程序中,凡是与共享资源有关的操作(如存储分配、进行IO传输及管理文件等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。这样可以保证系统的稳定性和安全性,防止用户进行非法操作。

这些系统调用按功能大致可分为如下几类。

  • 设备管理。完成设备的请求或释放,以及设备启动等功能。
  • 文件管理。完成文件的读、写、创建及删除等功能。
  • 进程控制。完成进程的创建、撤销、阻塞及唤醒等功能。
  • 进程通信。完成进程之间的消息传递或信号传递等功能。
  • 内存管理。完成内存的分配、回收以及获取作业占用内存区大小及始址等功能。

系统调用的过程 

 

如果一个应用程序执行了陷入指令,也就意味着应用程序主动的把CPU的控制权主动的还给了系统,用这种方式来请求操作系统的服务,注意陷入指令属于非特权指令

系统调用的处理需要由操作系统内核程序负责完成,要运行在内核态。用户程序可以执行陷入指令(又称访管指令或trap指令)来发起系统调用,请求操作系统提供服务。可以这么理解,用户程序执行“陷入指令”,相当于把 CPU的使用权主动交给操作系统内核程序(CPU 状态会从用户态进入内核态),之后操作系统内核程序再对系统调用请求做出相应处理。处理完成后,操作系统内核程序又会把CPU的使用权还给用户程序(即CPU状态会从核心态回到用户态)。

这么设计的目的是:用户程序不能直接执行对系统影响非常大的操作,必须通过系统调用的方式请求操作系统代为执行,以便保证系统的稳定性和安全性,防止用户程序随意更改或访问重要的系统资源,影响其他进程的运行(就相当于找一个公共的大哥对这些资源进行裁决,用之前问大哥,看看大哥给不给你用)。

  • 操作系统的运行环境就可以理解为用户通过操作系统运行上层程序(如系统提供的命令解释程序或用户自编程序),而这个上层程序的运行依赖于操作系统的底层管理程序提供服务支持,当需要管理程序服务时,系统则通过硬件中断机制进入核心态,运行管理程序;
  • 也可能是程序运行出现异常情况,被动地需要管理程序的服务,这时就通过异常处理来进入核心态。
  • 管理程序运行结束时,用户程序需要继续运行,此时通过相应的保存的程序现场退出中断处理程序或异常处理程序,返回断点处继续执行。

下面是一些由用户态传向核心态的例子

  • 用户程序要求操作系统的服务,即系统调用
  • 发生一次中断
  • 用户程序中产生了一个错误状态
  • 用户程序中企图执行一条特权指令
  • 从核心态转向用户态由一条指令实现,这条指令也是特权命令,一般是中断返回指令

注意:由用户态进入核心态,不仅状态需要切换,而且所用的堆栈也可能需要由用户堆栈切换为系统堆栈,但这个系统堆栈也是属于该进程的。
若程序的运行由用户态转到核心态,则会用到访管指令,访管指令是在用户态使用的,所以它不可能是特权指令。

操作系统的体系结构

操作系统的内核

实现程序并发就一定离不开时钟管理

这些内核程序必须运行在内核态,与硬件关联较紧密的模块一定是放在内核态,若是不会涉及硬件的管理工作,有些操作系统则会将这些管理功能不放在内核中,而仅仅保留与硬件接触最紧密的部分,因此这就引出了两种截然不同的内核设计方法,所有的功能都包含在操作系统内核中的,这种叫做大内核,只保留与硬件功能最紧密的叫做微内核.

  • 若是使用微内核这种结构,则微内核的管理功能是运行在内核态,而类如进程管理等功能则是运行在用户态,这会对系统的性能造成一定的影响
  • 若是使用大内核这种结构,当要进行进程管理等一系列操作的时候,CPU从用户态变为内核态开始运行这一系列的内核程序
  • 若是使用微内核的,应用程序向操作系统提出服务的请求,而进程管理这个模块处理的时候也是需要得到内核的支持,所以每一个模块都需要从用户态转到内核态,服务完成之后又会从内核态转用户态.

从操作系统的内核架构来划分,可分为宏内核和微内核。
宏内核,也称单内核或大内核,是指将系统的主要功能模块都作为一个紧密联系的整体运行在核心态,从而为用户程序提供高性能的系统服务。因为各管理模块之间共享信息,能有效利用相互之间的有效特性,所以具有无可比拟的性能优势。
随着体系结构和应用需求的不断发展,需要操作系统提供的服务越来越复杂,操作系统的设计规模急剧增长,操作系统也面临着“软件危机”困境。就像一个人,越胖活动起来就越困难。所以就出现了微内核技术,就是将一些非核心的功能移到用户空间,这种设计带来的好处是方便扩展系统,所有新服务都可以在用户空间增加,内核基本不用去做改动。
目前主流的操作系统,如Windows.Android、iOS、macOS、Linux等,都是基于宏内核的构架。但也应注意到,微内核和宏内核一直是同步发展的,目前主流的操作系统是广泛吸取微内核构架的优点而后揉合而成的混合内核。谷歌的Fuchsia和华为的鸿蒙OS,都瞄准了微内核构架。
微内核
微内核构架,是指将内核中最基本的功能保留在内核,而将那些不需要在核心态执行的功能移到用户态执行,从而降低内核的设计复杂性。那些移出内核的操作系统代码根据分层的原则被划分成若干服务程序,它们的执行相互独立,交互则都借助于微内核进行通信。
微内核结构将操作系统划分为两大部分:微内核和多个服务器。微内核是指精心设计的、能实现操作系统最基本核心功能的小型内核,通常包含:①与硬件处理紧密相关的部分:②一些较基本的功能:③客户和服务器之间的通信。这些部分只是为构建通用操作系统提供一个重要基础,这样就可以确保将内核做得很小。

操作系统中的绝大部分功能都放在微内核外的一组服务器(进程)中实现,(如用于提供对进程(线程〉进行管理的进程(线程)服务器、提供虚拟存储器管理功能的虚拟存储器服务器等),它们都是作为进程来实现的,运行在用户态,客户与服务器之间是借助微内核提供的消息传递机制来实现交互的。
在微内核结构中,为了实现高可靠性,只有微内核运行在内核态,其余模块都运行在用户态,一个模块中的错误只会使这个模块崩溃,而不会使整个系统崩溃。例如,文件服务代码运行时出了问题,宏内核因为文件服务是运行在内核态的,系统直接就崩溃了。而微内核的文件服务是运行在用户态的,只要把文件服务功能强行停止,然后重启,就可以继续使用,系统不会崩溃。
(2)微内核的基本功能
微内核结构通常利用==“机制与策略分离”的原理来构造OS结构,将机制部分以及与硬件紧密相关的部分放入微内核

微内核通常具有如下功能:

  • ①进程(线程)管理。进程(线程)之间的通信功能是微内核OS最基本的功能,此外还有进程的切换、进程的调度,以及多处理机之间的同步等功能,都应放入微内核中==。举个例子,为实现进程调度功能,需要在进程管理中设置一个或多个进程优先级队列,这部分属于调度功能的机制部分,应将它放入微内核中。而对用户进程如何分类,以及优先级的确认方式,则属于策略问题,可将它们放入微内核外的进程管理服务器中。
  • ②低级存储器管理。在微内核中,只配置最基本的低级存储器管理机制,如用于实现将逻辑地址变换为物理地址等的页表机制和地址变换机制,这一部分是依赖于硬件的,因此放入微内核。而实现虚拟存储器管理的策略,则包含应采取何种页面置换算法,采用何种内存分配与回收的策略,应将这部分放在微内核外的存储器管理服务器中。
  • ③中断和陷入处理。微内核OS将与硬件紧密相关的一小部分放入微内核,此时微内核的主要功能是捕获所发生的中断和陷入事件,并进行中断响应处理,在识别中断或陷入的事件后,再发送给相关的服务器来处理,故中断和陷入处理也应放入微内核。
  • 微内核操作系统将进程管理、存储器管理以及IO管理这些功能一分为二,属于机制的很小一部分放入微内核,而绝大部分放入微内核外的各种服务器实现,大多数服务器都要比微内核大。因此,在采用客户/服务器模式时,能把微内核做得很小

(3)微内核的特点
微内核结构的主要优点如下所示。

  • ①扩展性和灵活性。许多功能从内核中分离出来,当要修改某些功能或增加新功能时,只需在相应的服务器中修改或新增功能,或再增加一个专用的服务器,而无须改动内核代码。
  • ②可靠性和安全性。前面已举例说明。
  • ③可移植性。与CPU和IO硬件有关的代码均放在内核中,而其他各种服务器均与硬件平台无关,因而将操作系统移植到另一个平台上所需做的修改是比较小的。
  • ④分布式计算。客户和服务器之间、服务器和服务器之间的通信采用消息传递机制,这就使得微内核系统能很好地支持分布式系统和网络系统。

微内核结构的主要问题是性能问题,因为需要频繁地在核心态和用户态之间进行切换,操作系统的执行开销偏大。为了改善运行效率,可以将那些频繁使用的系统服务移回内核,从而保证系统性能,但这又会使微内核的容量明显地增大。

分层结构

每一层只能调用相邻更低一层提供的接口,若是我们在原有的两层之间新加一层,我们只需要保证向上层提供的接口,以及对下层的使用,因此加层是比较容易的

分层法是将操作系统分为若干层,最底层(层0)为硬件,最高层(层N)为用户接口,每
层只能调用紧邻它的低层的功能和服务(单向依赖)。
分层法的优点:

  • ①便于系统的调试和验证,简化了系统的设计和实现。第1层可先调试而无须考虑系统的其他部分,因为它只使用了基本硬件。第1层调试完且验证正确之后,就可以调试第2层,如此向上。如果在调试某层时发现错误,那么错误应在这一层上,这是因为它的低层都调试好了。
  • ②易扩充和易维护。在系统中增加、修改或替换一层中的模块或整层时,只要不改变相应层间的接口,就不会影响其他层。

分层法的问题:

  • ①合理定义各层比较困难。因为依赖关系固定后,往往就显得不够灵活。
  • ②效率较差。操作系统每执行一个功能,通常要自上而下地穿越多层,各层之间都有相应的层间通信机制,这无疑增加了额外的开销,导致系统效率降低。

模块化的操作系统 

因为模块间相互依赖,所以若是其中出了问题,则难以发现问题出现在哪

在划分模块时,如果将模块划分得太小,虽然能降低模块本身的复杂性,但会使得模块之间的联系过多,造成系统比较混乱:如果模块划分得过大,又会增加模块内部的复杂性,显然应在两者间进行权衡。此外,在划分模块时,要充分考虑模块的独立性问题,因为模块独立性越高,各模块间的交互就越少,系统的结构也就越清晰。衡量模块的独立性主要有两个标准;
内聚性,模块内部各部分间联系的紧密程度。内聚性越高,模块独立性越好。·
耦合度,模块间相互联系和相互影响的程度。耦合度越低,模块独立性越好。

  • 模块化的优点:①提高了操作系统设计的正确性、可理解性和可维护性;②增强了操作系统的可适应性:③加速了操作系统的开发过程。
  • 模块化的缺点:①模块间的接口规定很难满足对接口的实际需求。②各模块设计者齐头并进,每个决定无法建立在上一个已验证的正确决定的基础上,因此无法找到一个可靠的决定顺序。

 外核

不同于虚拟机克隆真实机器,另一种策略是对机器进行分区,给每个用户整个资源的一个子集。这样,某个虚拟机可能得到磁盘的0至1023盘块,而另一台虚拟机会得到磁盘的1024至2047盘块,等等。在底层中,一种称为外核(exokernel)的程序在内核态中运行。它的任务是为虚拟机分配资源,并检查使用这些资源的企图,以确保没有机器会使用他人的资源。每个用户层的虚拟机可以运行自己的操作系统,但限制只能使用已经申请并且获得分配的那部分资源
外核机制的优点是减少了映射层。在其他的设计中,每个虚拟机都认为它有自己的磁盘,其盘块号从0到最大编号,这样虚拟机监控程序就必须维护一张表格以重映像磁盘地址(或其他资源),有了外核,这个重映射处理就不需要了。外核只需要记录已经分配给各个虚拟机的有关资源即可。这种方法还有一个优点,它将多道程序(在外核内)与用户操作系统代码(在用户空间内)加以分离,而且相应的负载并不重,因为外核所做的只是保持多个虚拟机彼此不发生冲突。

操作系统引导

操作系统(如 Windows、Linux等)是一种程序,程序以数据的形式存放在硬盘中,而硬盘通常分为多个区,一台计算机中又有多个或多种外部存储设备。操作系统引导是指计算机利用CPU运行特定程序,通过程序识别硬盘,识别硬盘分区,识别硬盘分区上的操作系统,最后通过程序启动操作系统,一环扣一环地完成上述过程。
常见操作系统的引导过程如下:

  • 激活CPU。激活的CPU读取ROM中的 boot程序,将指令寄存器置为BIOS(基本输入/输出系统)的第一条指令,即开始执行 BIOS的指令。
  • ②硬件自检。启动BIOS程序后,先进行硬件自检,检查硬件是否出现故障。如有故障,主板会发出不同含义的蜂鸣,启动中止;如无故障,屏幕会显示CPU、内存、硬盘等信息。
  • 加载带有操作系统的硬盘。硬件自检后,BIOS开始读取 Boot Sequence(通过CMOS里保存的启动顺序,或者通过与用户交互的方式),把控制权交给启动顺序排在第一位的存储设备,然后CPU将该存储设备引导扇区的内容加载到内存中。
  • 加载主引导记录MBR。硬盘以特定的标识符区分引导硬盘和非引导硬盘。如果发现一个存储设备不是可引导盘,就检查下一个存储设备。如无其他启动设备,就会死机。主引导记录MBR的作用是告诉CPU去硬盘的哪个主分区去找操作系统。
  • 扫描硬盘分区表,并加载硬盘活动分区。(MBR包含硬盘分区表,硬盘分区表以特定的标识符区分活动分区和非活动分区。主引导记录扫描硬盘分区表,进而识别含有操作系统的硬盘分区(活动分区))。找到硬盘活动分区后,开始加载硬盘活动分区,将控制权交给活动分区。
  • 加载分区引导记录PBR。读取活动分区的第一个扇区,这个扇区称为分区引导记录(PBR),其作用是寻找并激活分区根目录下用于引导操作系统的程序(启动管理器)。
  • ⑦加载启动管理器。分区引导记录搜索活动分区中的启动管理器,加载启动管理器。
  • ⑧加载操作系统。

 虚拟机

 虚拟机:使用虚拟化技术,将一台物理机器虚拟化为多台虚拟机器(VirtualMachine,VM),每个虚拟机器都可以独立运行一个操作系统
同义术语:虚拟机监控程序、虚拟机管理程序。

  • 第一类会将物理机器虚拟化为多台虚拟机器,会将整个应用资源划分为多个部分,给每一台虚拟机使用,每一个虚拟机上可以按照各自的操作系统,CPU时间片进行划分,磁盘内存进行区域划分,只有虚拟机管理程序是运行在内核态,只有它可以使用特权最高的那些指令,而上层的操作系统和 应用程序是运行在用户态,但是上层的操作系统并不知道,所以依然会使用一些特权指令,但是只有虚拟机管理程序是在内核态,不能让操作系统使用这些特权指令,若是上层要使用特权指令,则会被虚拟机管理程序截获,会将这些特权指令进行一些等价的转化,给上层一种执行成功的感觉
  • 第二类不是直接运行在硬件上,而是运行在宿主操作系统上,如VMware,这个虚拟机管理程序想要给虚拟机分配硬件资源,只能先请求宿主操作系统给他进行分配虚拟内存资源,然后虚拟机管理程序进行再分配

第一类虚拟机管理程序
从技术上讲,第一类虚拟机管理程序就像一个操作系统,因为它是唯一一个运行在最高特权级的程序。它在裸机上运行并且具备多道程序功能。虚拟机管理程序向上层提供若干台虚拟机,这些虚拟机是裸机硬件的精确复制品。由于每台虚拟机都与裸机相同,所以在不同的虚拟机上可以运行任何不同的操作系统。
虚拟机作为用户态的一个进程运行,不允许执行敏感指令。然而,虚拟机上的操作系统认为自己运行在内核态(实际上不是),称为虚拟内核态。虚拟机中的用户进程认为自己运行在用户态(实际上确实是)。当虚拟机操作系统执行了一条CPU处于内核态才允许执行的指令时,会陷入虚拟机管理程序。
在支持虚拟化的CPU上,虚拟机管理程序检查这条指令是由虚拟机中的操作系统执行的还是由用户程序执行的。如果是前者,虚拟机管理程序将安排这条指令功能的正确执行。否则,虚拟机管理程序将模拟真实硬件面对用户态执行敏感指令时的行为。
在过去不支持虚拟化的CPU 上,真实硬件不会直接执行虚拟机中的敏感指令,这些敏感指令被转为对虚拟机管理程序的调用,由虚拟机管理程序模拟这些指令的功能。
第二类虚拟机管理程序
第二类虚拟机管理程序。它是一个依赖于Windows、Linux等操作系统分配和调度资源的程序,很像一个普通的进程。第二类虚拟机管理程序仍然伪装成具有CPU和各种设备的完整计算机。VMware Workstation是首个X86平台上的第二类虚拟机管理程序。
运行在两类虚拟机管理程序上的操作系统都称为客户操作系统。对于第二类虚拟机管理程序,运行在底层硬件上的操作系统称为宿主操作系统。
首次启动时,第二类虚拟机管理程序像一台刚启动的计算机那样运转,期望找到的驱动器可以是虚拟设备。然后将操作系统安装到虚拟磁盘上(其实只是宿主操作系统中的一个文件)。客户操作系统安装完成后,就能启动并运行。
虚拟化在Web主机领域很流行。没有虚拟化,服务商只能提供共享托管(不能控制服务器的软件)和独占托管(成本较高)。当服务商提供租用虚拟机时,一台物理服务器就可以运行多个虚拟机,每个虚拟机看起来都是一台完整的服务器,客户可以在虚拟机上安装自己想用的操作系统和软件,但是只需支付较低的费用。这就是市面上常见的“云”主机。
有的教材将第一类虚拟化技术称为裸金属架构,将第二类虚拟化技术称为寄居架构。

 进程

进程的概念与实体

进程是进程实体运行过程,是系统进行资源分配和调度的一个独立单位。

进程实现操作系统的并发性和共享性。

  • 程序:是静态的,就是个存放在磁盘里的可执行文件,如:QQ.exe。
  • 进程:是动态的,是程序的一次执行过程,或者是一个正在运行的程序,如:可同时启动多次QQ程序。
  • 进程实体:即进程映像,是静态的,可理解为进程的一次时刻的状态。
  • 作业:用户向计算机提交的一项任务,是静态的,它通常是一个批处理程序或一个后台程序。(放在外存里没有投入CPU运行的程序)

 当进程被创建时,操作系统会为该进程分配一个唯一的、不重复的“身份证号”--PID(进程ID)

 进程的组成

若不考察进程实体,进程就可以理解为进程实体 

PCB是进程存在的唯一标志,当进程被创建时,操作系统为其创建PCB,当进程结束时,会回收其PCB。

① PCB,即进程控制块,操作系统需要对各个并发运行的进程进行管理, 但凡管理时所需要的信息,都会被放在 PCB 中。

② PCB 是进程存在的唯一标志。

③ PCB 存于内存的内核区,注意内存的内核区和 OS 的内核态的区别,内核程序运行在内核态。

①PCB 是给操作系统用的,程序段和数据段是给进程自己用的。

②引入进程实体的概念后,可把进程定义为是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。

进程的特征

  • 动态性:进程是程序的一次执行过程,是动态地产生、变化和消亡的;动态性是进程最基本的特征。
  • 并发性:内存中有多个进程实体,各进程可并发执行
  • 独立性:进程是能独立运行、独立获得资源、独立接受调度的基本单位
  • 异步性:各进程按各自独立的、不可预知的速度向前推进,异步性会导致并发程序执行结果的不确定性。
  • 结构性:每个进程都会配置一个PCB。结构上看,进程由程序段、数据段、PCB组成

进程的状态与转换 

  • 就绪态。已具有运行条件,但无空闲CPU,暂时不能运行;×CPU√其他所需资源

系统中处于就绪状态的进程可能有多个,通常将它们排成一个队列,称为就绪队列。

  • 创建态。进程正在被创建,尚未转到就绪态。OS为进程分配系统资源、初始化PCB

    首先申请一个空白PCB,并向PCB中填写用于控制和管理进程的信息

    然后为该进程分配运行时所必须的资源

    最后把该进程转入就绪态并插入就绪队列

    但是,如果进程所需的资源尚不能得到满足,如内存不足,则创建工作尚未完成,进程此时所处的状态称为创建态。

  • 运行态。占有CPU,并在CPU上运行;√CPU√其他所需资源

  • 阻塞态,又称等待态。因等待某一事件暂时不能运行;×CPU×其他所需资源

系统通常将处于阻塞态的进程也排成一个队列,甚至根据阻塞原因的不同,设置多个阻塞队列。

  • 终止态。进程正从系统中消失,进程正常结束或其他原因退出运行。OS回收进程拥有的资源,撤销PCB

  • 就绪态一>运行态:进程被调度
  • 运行态一>就绪态:时间片到 or CPU被其他进程抢占
  • 运行态一>阻塞态:等待系统资源分配or等待某事件发生(主动行为)
  • 阻塞态一>就绪态:资源分配到位,等待的事件发生(被动行为)
  • 创建态一>就绪态:系统完成创建进程相关的工作
  • 运行态一>终止态:进程运行结束 or 运行过程中遇到不可修复的错误

进程的组织

链接方式  

链接方式是将同一状态的进程的PCB组成一个双向链表,称为进程队列。

  • 结构:每个队列的队首和队尾都有一个指针,指向第一个和最后一个PCB。每个PCB中也有两个指针,分别指向前一个和后一个PCB。这样,就可以方便地在队列中插入或删除PCB。
  • 优点:简单、灵活
  • 缺点:查找效率低,需要遍历链表

索引方式

索引方式是将所有的PCB存放在一张索引表中,每个表项包含一个PCB的地址和状态信息。

  • 结构:索引表可以是顺序表或散列表,可以按照进程号或其他关键字进行排序或散列。
  • 优点:查找效率高,可以快速定位到某个PCB
  • 缺点:需要额外的空间存储索引表,且索引表的大小受限于内存容量

进程控制

进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能。
简化理解:反正进程控制就是要实现进程状态转换

  • 进程控制用原语实现(原语的执行具有“原子性”,一气呵成)
  • 如果不能一气呵成,可能会导致操作系统中的某些关键数据结构信息不统一的情况

可以用“关中断指令”和“开中断指令”这两个特权指令实现原子性

 CPU执行了关中断指令之后,就不再例行检查中断信号,直到执行开中断指令之后才会恢复检查。这样,关中断、开中断 之间的这些指令序列就是不可被中断的,这就实现了“原子性”

进程状态相关的原语

应用请求(父子进程)

允许一个进程创建另一个进程,此时创建者称为父进程,被创建的进程称为子进程

  • 进程可以继承父进程所拥有的资源。
  • 当子进程被撤销时,应将其从父进程那里获得的资源归还给父进程。
  • 在撤销父进程时,通常也会同时撤销其所有的子进程。

  •  撤销原语:终止进程时使用

  • 唤醒原语和阻塞原语必须成对使用 

运行环境信息 

无论哪个进程控制原语,要做的无非三类事情:

  • 1.更新PCB中的信息(修改进程状态(state),保存/恢复运行环境)
  • 2.将PCB插入合适的队列
  • 3.分配/回收资源

进程通信

进程间通信《Inter-Process Communication,IPC)是指两个进程之间产生数据交互。

低级通信方式:PV操作。高级通信方式:共享存储、消息传递、管道通信。

为什么进程通信需要操作系统支持

  • 进程是分配系统资源的单位(包括内存地址空间),因此各进程拥有的内存地址空间相互独立。
  • 为了保证安全,一个进程不能直接访问另一个进程的地址空间

共享存储

设置一个共享空间(并映射到进程的虚拟地址空间),通过对其进行读/写操作实现信息交换

为了避免出错,各个进程对共享空间的访问应该是互斥的(有通信进程自己负责实现互斥)

在对共享空间进行写/读操作时,需要使用同步互斥工具(如PV操作)。

  • 其于存储区的共享:操作系统在内存中划出一块共享存储区,数据的形式、存放位置都由通信进程控制,而不是操作系统。这种共享方式速度很快,是一种高级通信方式。
  • 基于数据结构的共享:比如共享空间里只能放一个长度为10的数组。这种共享方式速度慢、限制多,是一种低级通信方式

 进程之间共享空间需要通过特殊的系统调用实现;进程内线程共享进程空间

 消息传递

 在消息传递系统中,进程间的数据交换以格式化的消息(Message)为单位。进程通过操作系统提供的“发送信息/接受信息”两个原语进行数据交换。

微内核操作系统中,微内核与服务器之间的通信就采用了消息传递机制。

 直接通信方式

发送进程直接把消息发送给接收进程,并将它挂在接收进程的消息缓冲队列上,接收进程从消息缓冲队列中取得消息。

  • 直接发给目标,目标直接从源头接受
  • 相当于京东邮寄到家 
 间接通信方式

 进程通过信箱间接地通信,将消息发送到某个中间实体,接收进程从中间实体取得消息。该通信方式广泛应用于计算机网络中。

  • 源头发给中间商,目标从中间商取
  • 相当于普通快递,得去驿站取
 管道通信方式

管道是一个特殊的共享文件,又名pipe文件。其实就是在内存中开辟一个大小固定的内存缓冲区(循环队列)管道通信允许两个进程按生产者-消费者方式进行通信。各进程要互斥访问管道

 管道通信带有先进先出的顺序,地址是连续的

 共享通信无序,地址是范围随机的

  • 写满时,不能再写,读空时,不能再读

 一个管道只能实现半双工通信;实现双向同时通信要建立两个管道

管道本质上是一种特殊的文件。相比于普通的文件通信,其区别如下:

  • 限制管道的大小。管道文件是一个固定大小的缓冲区,使得它的大小不像普通文件那样不加检验地增长。
  • 读进程也可能工作得比写进程快。读空时再读管道会被阻塞,而不是调用返回文件结束。
  • 管道中的数据一旦被读出,就彻底消失。因此,当多个进程读同一个管道时,可能会错乱。对此,通常有两种解决方案:
  • ①一个管道允许多个写进程,一个读进程(2014年408真题高教社官方答案);
  • ②允许有多个写进程,多个读进程,但系统会让各个读进程轮流从管道中读数据(Liux的方案)。

 管道只能由创建进程所访问,当父进程创建一个管道后,由于管道是一种特殊文件,子进程会继承父进程的打开文件,因此子进程也继承父进程的管道,并使用它来与父进程进进行通信。

 线程

线程的基本概念

线程可理解为轻量级进程,它是一个基本的CPU执行单元,也是程序执行流的最小单位。

线程由线程ID、程序计数器、寄存器集合和堆栈组成。

  • 引入进程的目的是更好地使多道程序并发执行,提高资源利用率和系统吞吐量;
  • 而引入线程的目的则是减小程序在并发执行时所付出的时空开销,提高操作系统的并发性能。(进程之间可以并发执行,进程的线程之间也能并发的执行)
  • 引入线程后,进程只作为除CPU之外的系统资源的分配单元(如打印机、内存地址空间等都是分配给进程的),线程则作为处理机的分配单元

带来的变化 

线程的属性 

多线程操作系统中的进程已不再是一个基本的执行实体,但它仍具有与执行相关的状态。所谓进程处于“执行”状态,实际上是指该进程中的某线程正在执行。

  • 线程是处理机调度的单位
  • 多CPU计算机中,各个线程可占用不同的CPU
  • 每个线程都有一个线程ID、线程控制块(TCB)
  • 线程也有就绪、阻塞、运行三种基本状态
  • 线程几乎不拥有系统资源(都在进程里)
  • 同一进程的不同线程间共享进程的资源
  • 由于共享内存地址空间,同一进程中的线程间通信甚至无需系统干预
  • 同一进程中的线程切换,不会引起进程切换
  • 不同进程中的线程切换,会引起进程切换
  • 切换同进程内的线程,系统开销很小
  • 切换进程,系统开销较大

注:线程是处理机调度的单位,这里的线程指的是操作系统看得见的内核级线程,内核级线程是处理机分配的单位 。

同进程的线程之间可以共享进程的代码段、全局变量、打开的文件,不共享线程各自的栈指针等TCB内容

进程的实现方法 

线程的实现可以分为两类:用户级线程 和 内核级线程。内核级线程又称内核支持的线程。

用户级线程 

在用户级线程中,有关线程管理(创建、撤销和切换等)的所有工作都由应用程序在用户空间中完成,内核意识不到线程的存在,因此说用户级线程对操作系统透明。

  • 用户级线程由应用程序通过线程库实现,所有的线程管理工作都由应用程序负责(包括线程切换)
  • 用户级线程中,线程切换可以在用户态下即可完成,无需操作系统干预。
  • 在用户看来,是有多个线程。但是在操作系统内核看来,并意识不到线程的存在。“用户级线程”就是“从用户视角看能看到的线程
  • 优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高
  • 缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行。

内核级线程 

内核级线程是在内核的支持(由操作系统支持)下运行的,线程管理的所有工作也是在内核空间内实现的。

  • 内核级线程的管理工作由操作系统内核完成
  • 线程调度、切换等工作都由内核负责,因此**内核级线程的切换**必然需要在核心态下才能完成。
  • 操作系统会为每个内核级线程建立相应的TCB(Thread Control Block,线程控制块),通过TCB对线程进行管理。“内核级线程”就是“从操作系统内核视角看能看到的线程
  • 优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。  
               多线程可在多核处理机上并行执行。
  • 缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。

组合线程

有些系统使用组合方式的多线程实现。在组合实现方式中,内核支持多个内核级线程的建立、调度和管理,同时允许用户程序建立、调度和管理用户级线程

  • 一些内核级线程对应多个用户级线程,这是用户级线程通过时分多路复用内核级线程实现的。
  • 同一进程中的多个线程可以同时在多处理机上并行执行,
  • 且在阻塞一个线程时不需要将整个进程阻塞

线程库 

线程库是为程序员提供创建和管理线程的API。实现方式有以下两种。

  • 用户空间中提供一个没有内核支持的库。这种库的所有代码和数据结构都位于用户空间中。这意味着,调用库内的一个函数只导致用户空间中的一个本地函数的调用
  • 实现由操作系统直接支持的内核级的一个库。对于这种情况,库内的代码和数据结构位于内核空间。调用库中的一个API函数通常会导致对内核的系统调用

多线程模型

在支持内核级线程的系统中,根据用户级线程和内核级线程的映射关系,可以划分为几种多线程模型

一对一模型

一个用户级线程映射到一个内核级线程。每个用户进程有与用户级线程同数量的内核级线程。

  • 优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。(内核级线程优点)
  • 缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。(内核级线程缺点)

多对一模型

多个用户级线程映射到一个内核级线程。且一个进程只被分配一个内核级线程。

  • 优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高(用户级线程优点)
  • 缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行(用户级线程缺点)

多对多模型

n用户及线程映射到m个内核级线程(n>=m)。每个用户进程对应m个内核级线程。


克服了多对一模型并发度不高的缺点(一个阻塞全体阻塞),又克服了一对一模型中一个用户进程占用太多内核级线程,开销太大的缺点。还拥有上述两种模型各自的优点。

线程的状态与切换

进程的组织与控制

与进程类似,系统也为每个线程配置一个线程控制块TCB,用于记录控制和管理线程的信息。

线程控制块通常包括

  • ①线程标识符
  • ②一组寄存器,包括程序计数器、状态寄存器和通用寄存器
  • ③线程运行状态,用于描述线程正处于何种状态
  • ④优先级
  • ⑤线程专有存储区,线程切换时用于保存现场等
  • ⑥堆栈指针,用于过程调用时保存局部变量及返回地址等。

同一进程中的所有线程都完全共享进程的地址空间和全局变量。

各个线程都可以访问进程地址空间的每个单元,所以一个线程可以读、写或甚至清除另一个线程的堆栈。

线程的创建

  • 用户程序启动时,通常仅有一个称为“初始化线程”的线程正在执行,其主要功能是用于创建新线程。
  • 在创建新线程时,需要利用一个线程创建函数,并提供相应的参数,如指向线程主程序的入口指针、堆栈的大小、线程优先级等。线程创建函数执行完后,将返回一个线程标识符

线程的终止

  • 当一个线程完成自己的任务后,或线程在运行中出现异常而要被强制终止时,由终止线程调用相应的函数执行终止操作。
  • 但是有些线程(主要是系统线程)一旦被建立,便一直运行而不会被终止。通常,线程被终止后并不立即释放它所占有的资源,只有当进程中的其他线程执行了分离函数后,被终止线程才与资源分离,此时的资源才能被其他线程利用。
  • 被终止但尚未释放资源的线程仍可被其他线程调用,以使被终止线程重新恢复运行。

 处理机调度

处理机调度是对处理机进行分配,即从就绪队列中按照一定的算法(公平、高效的原则)去选择一个进程并将处理机分配给它运行,以实现进程并发地执行。

调度对层次

一个作业从提交开始直到完成,要经历以下三级调度,如下图所示。

调度的三个层次 

高级调度(作业调度)
  • 内存空间有限时,无法将用户提交的作业全部放入内存,需要按一定的原则从外存的作业后备队列中挑选一个作业调入内存,并创建进程。
  • 每个作业只调入一次,调出一次。作业调入时会建立PCB,调出时才撤销PCB。

作业:一个具体的任务

用户向系统提交一个作业≈用户让操作系统启动一个程序(来处理一个具体的任务)

多道批处理系统中大多配有作业调度,而其他系统中通常不需要配置作业调度。

  • 发生频率最低 外存→内存(面向作业)
中级调度(内存调度)

内存不够时,可将某些进程的数据调出外存。等内存空闲或者进程需要运行时,按照某种策略从 挂起队列中选择合适的进程重新调入内存。

暂时调到外存等待的进程状态为挂起状态。被挂起的进程PCB会被组织成挂起队列

  • 外存→内存(面向进程)
低级调度(进程调度/处理机调度)

在内存中的按照某种策略从 就绪队列 中选取一个进程,将处理机分配给它。

  • 发生频率高 内存→CPU
七状态模型 

 挂起和阻塞的区别: 两种状态都不获得 CPU 服务,但挂起状态将进程调到外存,而阻塞态还在内存中

 三层调度的联系与对比
  • 三层调度联系

    • 1)作业调度为进程活动做准备,进程调度使进程正常活动起来。
    • 2)中级调度将暂时不能运行的进程挂起,中级调度处于作业调度和进程调度之间。
    • 3)作业调度次数少,中级调度次数略多,进程调度频率最高。
    • 4)进程调度是最基本的,不可或缺

调度的目标

不同的调度算法具有不同的特性,在选择调度算法时,必须考虑算法的特性。评价标准如下。

1.CPU利用率:指CPU“忙碌”的时间占总时间的比例。

2.系统吞吐率:单位时间内完成作业的数量。

3.周转时间:指从作业被提交给系统开始,到作业完成为止的这段时间间隔。

平均周转时间:指多个作业周转时间的平均值。

带权周转时间:作业周转时间与作业实际运行时间的比值。带权周转时间必然≥1平均带权周转时间:多个作业带权周转时间的平均值。

4.等待时间

等待时间,指进程/作业处于等待处理机状态时间之和,等待时间越长,用户满意度越低。完成-提交-运行

  • 对于进程来说,等待时间就是指进程建立后等待被服务的时间之和。

  • 对于作业来说,不仅要考虑建立进程后的等待时间,还要加上作业在外存后备队列中等待的时间。

平均等待时间:各个进程/作业等待时间的平均值。

5.响应时间:从用户提交请求到首次产生响应所用的时间。

调度的实现

1.调度程序(调度器)

用于调度和分派CPU 的组件称为调度程序,它通带由三部分组成,如图所示。

  • 排队器:将系统中的所有就绪进程按照一定的策略排成一个或多个队列,以便于调度程序选择。每当有一个进程转变为就绪态时,排队器便将它插入到相应的就绪队列中。
  • 分派器:依据调度程序所选的进程,将其从就绪队列中取出,将CPU分配给新进程。
  • 上下文切换器:在对处理机进行切换时,会发生两对上下文的切换操作:
    • 第一对,将当前进程的上下文保存到其PCB中,再装入分派程序的上下文,以便分派程序运行;        
    • 第二对,移出分派程序的上下文,将新选进程的CPU现场信息装入处理机的各个相应寄存器。

 2.调度的时机

  • 需要调度

    • 主动放弃:进程正常终止;运行过程中发生异常而终止;主动阻塞(比如等待IO)
    • 被动放弃:时间片用完;有更紧急的事情处理(I/O中断);有更高优先级的进程进入就结队列
  • 不能调度

    • 处理中断的过程中。中断处理过程复杂,与硬件密切相关,很难做到在中断处理过程中进行进程切换。

    • 进程在操作系统内核程序临界区中(不是临界区)

    • 原子操作过程中(原语)。原子操作不可中断,要一气呵成(如之前讲过的修改PCB中进程状态标志,并把PCB放到相应队列)

临界资源:一个时间段内只允许一个进程使用的资源。各进程需要互斥地访问临界资源。

临界区:访问临界资源的那段代码。

内核程序临界区一般是用来访问某种内核数据结构的,比如进程的就绪队列(由各就绪进程的PCB组成)

  • 内核程序临界区访问的临界资源如果不尽快释放的话,极有可能影响到操作系统内核的其他管理工作。因此在访问内核程序临界区期间不能进行调度与切换
  • 普通临界区访问的临界资源(比如打印机这种io设备)不会直接影响操作系统内核的管理工作。因此在访问普通临界区时可以进行调度与切换

进程调度的方式

非剥夺调度方式

  1. 又称非抢占方式。即,只允许进程主动放弃处理机。在运行过程中即便有更紧迫的任务到达,当前进程依然会继续使用处理机,直到该进程终止主动要求进入阻塞态
  2. 实现简单,系统开销小但是无法及时处理紧急任务,适合于早期的批处理系统

剥夺调度方式

  •      1. 又称抢占方式。当一个进程正在处理机上执行时,如果有一个更重要或更紧迫的进程需要使用处理机,则==立即暂停在执行的进程==,将处理机分配给更重要紧迫的那个进程。
  •      2. 可以优先处理更紧急的进程,也可实现让各进程按时间片轮流执行的功能(通过时钟中断)。适合于分时操作系统、实时操作系统

 进程切换

“狭义的进程调度”与“进程切换”的区别:

  • 狭义的进程调度指的是从就绪队列中选中一个要运行的进程。(这个进程可以是刚刚被暂停执行的进程(自己)也可能是另一个进程,后一种情况就需要进程切换)
  • 进程切换是指一个进程让出处理机,由另一个进程占用处理机的过程。
  • 广义的进程调度包含了选择一个进程和进程切换两个步骤。

 进程切换(上下文切换)的过程主要完成了:

  • 1.对原来运行进程各种数据的保存
  • 2.对新的进程各种数据的恢复
  • (如:程序计数器、程序状态字、各种数据寄存器等处理机现场信息,这些信息一般保存在进程控制块)

上下文:某一时刻CPU寄存器和程序计数器的内容。

切换流程

  • 挂起一个进程,保存CPU上下文,包括程序计数器和其他寄存器。
  • 更新PCB信息。
  • 把进程的PCB移入相应的队列,如就绪、在某事件阻塞等队列。
  • 选择另一个进程执行,并更新其PCB。
  • 跳转到新进程PCB中的程序计数器所指向的位置执行。
  • 恢复处理机上下文。
  • 上下文切换的消耗

    上下文切换需要消耗大量CPU时间,有些处理器有多个寄存器组,则切换只需改变指针。

    进程切换是有代价的,因此如果过于频繁的进行进程调度、切换,必然会使整个系统的效率降低,使系统大部分时间都花在了进程切换上,而真正用于执行进程的时间减少。

上下文切换与模式切换

  • 模式切换是用户态和内核态之间的切换,CPU逻辑上可能还在执行同一进程。用户进程最开始都运行在用户态,若进程因中断或异常进入核心态运行,执行完后又回到用户态刚被中断的进程运行。
  • 上下文切换切换了进程,只能发生在内核态,它是多任务操作系统中的一个必需的特性。

闲逛进程

调度程序永远的备胎,没有其他就绪进程时,运行闲逛进程(idle)

特性:

  • 优先级最低;
  • 可以是0地址指令,占一个完整的指令周期(指令周期末尾例行检查中断)
  • 能耗低

闲逛进程不需要CPU之外的资源,它不会被阻塞。

两种线程的调度

  • 用户级线程调度。由于内核并不知道线程的存在,所以内核还是和以前一样,选择一个进程,并给予时间控制。由进程中的调度程序决定哪个线程运行。
  • 内核级线程调度。内核选择一个特定线程运行,通常不用考虑该线程属于哪个进程。对被选择的线程赋予一个时间片,如果超过了时间片,就会强制挂起该线程

用户级线程的线程切换在同一进程中进行,仅需少量的机器指令;

内核级线程的线程切换需要完整的上下文切换、修改内存映像、使高速缓存失效,这就导致了若干数量级的延迟。

调度算法

先来先服务(FCFS)

  • 算法思想:主要从“公平”的角度考虑(类似于我们生活中排队买东西的例子)

  • 算法规则:按照作业/进程到达的先后顺序进行服务

  • 用于作业/进程调度:

    • 用于作业调度时,考虑是哪作业先达后备队列
    • 用于进程调度时,考虑的是哪个进程先到达就绪队列
    • 优缺点:

      • 优点:公平、算法实现简单
      • 缺点:排在长作业(进程)后面的短作业需要等待很长时间,带权周转时间很大,对短作业来说用户体验不好。即,FCFS算法对长作业有利,对短作业有害(Eg:排队。)
  • 非抢占式的算法;不会导致饥饿

短作业优先(SJF)

  • 算法思想:追求最少的平均等待时间,最少的平均周转时间、最少的平均平均带权周转时间

  • 算法规则:最短的作业/进程优先得到服务(所谓“最短”,是指要求服务时间最短)

  • 用于作业/进程调度

    • 即可用于作业调度,也可用于进程调度。
    • 用于进程调度时为"短进程优先"(SPF,Shortest Process First)
  • 优缺点
    • 优点:“最短的”平均等待时间、平均周转时间
      • 在所有进程都几乎同时到达时,采用SJF调度算法的平均等待时间、平均周转时间最少;
      • “抢占式的短作业/进程优先调度算法(最短剩余时间优先,SRNT算法)的平均等待时间、平均周转时间最少”
    • 缺点:不公平对短作业有利,对长作业不利。可能产生饥饿现象。另外,作业进程的运行时间是由用户提供的,并不一定真实,不一定能做到真正的短作业优先。
  •  非/抢占式的算法:会导致饥饿。如果源源不断地有短作业/进程到来,可能使长作业/进程长时间得不到服务,产生“饥饿”现象。如果一直得不到服务,则称为“饿死

  • SJF和SPF是非抢占式的算法。但是也有抢占式的版本:最剩间优先算法(SRTN,Shortest Remaining Time Next.
    • 每当有进程加入就绪队列改变时就需要调度,如果新到达的进程剩余时间比当前运行的进程剩余时间更短,则由新进程抢占处理机,当前运行进程重新回到就绪队列。另外,当一个进程完成时也需要调度

  • 1.如果题目中未特别说明,所提到的“短作业/进程优先算法”默认是非抢占式
  • 2.很多书上都会说“SJF调度算法的平均等待时间、平均周转时间最少”
    严格来说,这个表述是错误的,不严谨的。之前的例子表明,最短剩余时间优先算法得到的平均等待时间、平均周转时间还要更少
    应该加上一个条件“在所有进程同时可运行时,采用SJF调度算法的平均等待时间、平均周转时间最少”;
    或者说“在所有进程都几乎同时到达时,采用SIF调度算法的平均等待时间、平均周转时间最少”;
  • 如果不加上述前提条件,则应该说“抢占式的短作业/进程优先调度算法(最短剩余时间优先,SRNT算法)的平均等待时间、平均周转时间最少”
  • 3.虽然严格来说,SJF的平均等待时间、平均周转时间并不一定最少,但相比于其他算法(如FCFS),SJF依然可以获得较少的平均等待时间、平均周转时间
  • 4.如果选择题中遇到“SIE算法的平均等待时间、平均周转时间最少”的选项,那最好判断其他选项是不是有很明显的错误,如果没有更合适的选项,那也应该选择该选项

高响应比优先(HRRN)

  • 算法思想:要综合考虑作业/进程的等待时间要求服务的时间

  • 算法规则:在每次调度时先计算各个作业/进程的响应比,选择响应比最高的作业/进程为其服务

    代入假设该进程完成的各种时间

  • 高响应比优先算法非抢占式的调度算法,只有当前运行的进程主动放弃CPU(正常/异常完成,或主动阻塞),才需要进行调度,调度时计算所有就绪进程的响应比,选响应比最高的进程上处理机。

  • 用于作业/进程调度:即可用于作业调度,也可用于进程调度

  • 优缺点

    • 综合考虑了等待时间和运行时间(要求服务时间)等待时间相同时,要求服务时间短的优先(SJF的优点);
    • 要求服务时间相同时,等待时间长的优先(FCFS的优点
    • 对于长作业来说,随着等待时间越来越久,其响应比也会越来越大,从而避免了长作业饥饿的问题

 这几种算法主要关心对用户的公平性、平均周转时间、平均等待时间等评价系统整体性能的指标,但是不关心“响应时间”,也并不区分任务的紧急程度,因此对于用户来说,交互性很糟糕。因此这三种算法一般适合用于早期的批处理系统

时间片轮转调度算法(RR)

  • 算法思想:公平地、轮流地各个进程服务,让每个进程在一定时间间隔内都可以得到响应

  • 算法规则:按照各进程到达就绪队列的顺序,轮流让各个进程执行一个时间片(如100ms)。若进程未在一个时间片(如100ms)内执行完,则剥夺处理机,将进程重新放到就绪队列队尾重新排队。

  • 用于作业/进程调度:用于进程调度(只有作业放入内存建立了相应的进程后,才能被分配处理机时间片)

  • 优缺点

    • 优点:公平;响应快,适用于分时操作系统;
    • 缺点:由于高频率的进程切换,因此有一定开销;不区分任务的紧急程度。
  • 抢占式的算法;不会导致饥饿

若进程未能在时间片内运行完,将被强行剥夺处理机使用权,因此时间片轮转调度算法属于抢占式的算法。由时钟装置发出时钟中断来通知CPU时间片已到 

  • 如果时间片太大,使得每个进程都可以在一个时间片内就完成,则时间片轮转调度算法退化为先来先服务调度算法,并且会增大进程响应时间。因此时间片不能太大
  • 另一方面,进程调度、切换是有时间代价的(保存、恢复运行环境),因此如果时间片太小,会导致进程切换过于频繁,系统会花大量的时间来处理进程切换,从而导致实际用于进程执行的时间比例减少。可见时间片也不能太小

优先级调度算法

  • 算法思想:随着计算机的发展,特别是实时操作系统的出现,越来越多的应用场景需要根据任务的紧急程度来决定处理顺序
  • 算法规则:每个作业/进程有各自的优先级,调度时选择优先级最高的作业/进程
  • 用于作业/进程调度:既可用于作业调度,也可用于进程调度。甚至,还会用于在之后会学习的I/O调度
  • 优缺点
    • 优点:用优先级区分紧急程度、重要程度,适用于实时操作系统。可灵活地调整对各种作业/进程的偏好程度
    • 缺点:若源源不断地有高优先级进程到来,则可能导致饥饿
  • 抢占式/非抢占式的算法;会导致饥饿

抢占式、非抢占式都有。做题时的区别在于:非抢占式只需在进程主动放弃处理机时进行调度即可,而抢占式还需在就绪队列变化时,检查是否会发生抢占。

 优先级排序

  • 系统进程优先级高于用户进程
  • 前台进程优先级高于后台进程
  • 操作系统更偏好I/O型进程(或称I/O繁忙型进程)
  • :与I/O型进程相对的是计算型进程(或称CPU繁忙型程)
    • I/O设备和CPU可以并行工作。如果优先让I/0繁忙型进程优先运行的话,则越有可能让IO设备尽早地投入工作,则资源利用率、系统吞吐量都会得到提升
  • 优先级分类:根据优先级是否可以动态改变,可将优先级分为静态优先级和动态优先级两种。
    • 静态优先级:创建进程时确定,之后一直不变
    • 动态优先级:创建进程时有一个初始值,之后会根据情况动态地调整优先级。
      • 可以从追求公平、提升资源利用率等角度考虑
        • 如果某进程在就绪队列中等待了很长时间,则可以适当提升其优先级
        • 如果某进程占用处理机运行了很长时间,则可适当降低其优先级
        • 如果发现一个进程频繁地进行I/0操作,则可适当提升其优先级

就绪队列未必只有一个,可以按照不同优先级来组织。另外,也可以把优先级高的进程排在更靠近队头的位置

多级队列调度算法

系统中按进程类型设置多个队列,进程创建成功后插入某个队列

  • 队列之间可采取固定优先级,或时间片划分
    • 固定优先级:高优先级空时低优先级进程才能被调度
    • 时间片划分:如三个队列分配时间50%、40%、10%
  • 各队列可采用不同的调度策略,如
    • 系统进程队列采用优先级调度、交互式队列采用RR、批处理队列采用FCFS

 多级反馈队列调度算法

  • 算法思想:对其他调度算法的折中权衡

  • 算法规则:

    • 1.设置多级就绪队列,各级队列==优先级从高到低时间片从小到大==
    • 2.新进程到达时先进入第1级队列,按FCFS原则排队等待被分配时间片,若用完时间片进程还未结束,则进程进入下一级队列队尾。如果此时已经是在最下级的队列,则重新放回该队列队尾
    • 3.只有第k级队列为空时,才会为k+1级队头的进程分配时间片
  • 用于作业/进程调度:用于进程调度

  • 优缺点 
    • 对各类型进程相对公平(FCFS的优点);
    • 每个新到达的进程都可以很快就得到响应(RR优点);
    • 短进程只用较少的时间就可完成(SPF优点);
    • 不必实现估计进程的运行时间(避免用户作假);
    • 可灵活地调整对各类进程的偏好程度,比如CPU密集型进程、IO密集型进程

拓展:可以将因I/O而阻塞的进程重新放回原队列,这样I/O型进程就可以保持较高优先级

抢占式的算法;导致饥饿 

在k级队列的进程运行过程中,若更上级的队列(1~k-1级)中进入了一个新进程,则由于新进程处于优先级更高的队列中,因此新进程会抢占处理机,原来运行的进程放回k级队列队尾。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值