抽时间整理了一下操作系统的学习笔记

抽时间整理了一下操作系统的学习笔记_第1张图片

1. 操作系统的概念及功能

操作系统(OS)是控制和管理整个计算机系统的硬件和软件资源,并合理地组织调度计算机的工作和资源的分配;以提供给用户和其他软件方便的接口和环境;它是计算机系统中最基本的系统软件。
抽时间整理了一下操作系统的学习笔记_第2张图片
操作系统的功能:

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

我们通过使用QQ软件的例子来体会操作系统的功能:
抽时间整理了一下操作系统的学习笔记_第3张图片
1.操作系统作为管理者需要做的事情
抽时间整理了一下操作系统的学习笔记_第4张图片
2.理解向上层提供方便易用的服务
封装思想:操作系统把一些丑陋的硬件功能封装成简单易用的服务,使用户能更方便地使用计算机,用户无需关心底层硬件的原理,只需要对操作系统发出命令即可。

那么具体提供方便易用的服务有哪些呢?
(1)GUI:图形化用户接口
用户可以使用形象的图形界面进行操作,而不再需要记忆复杂的命令,参数。
(2)命令接口
抽时间整理了一下操作系统的学习笔记_第5张图片
3.操作系统作为最接近硬件的层次
在这里插入图片描述
小结:
抽时间整理了一下操作系统的学习笔记_第6张图片

2. 操作系统的四个特征

操作系统有 并发,共享,虚拟,异步 这四个基本特征,其中并发和共享是两个最基本的特征,二者互为存在条件。

(1)并发:指两个或多个事件在同一时间间隔内发生。在这些事件宏观上是同时发生的。
注意:这里通常与并行混淆,并行是指两个或多个事件在同一时刻同时发生。

为了方便理解,我们来个例子!老渣和小渣
抽时间整理了一下操作系统的学习笔记_第7张图片

  1. 操作系统的并发性:指计算机系统中同时运行着多个程序,这些程序宏观上看是同时运行着的,而微观上看是交替运行的。操作系统就是伴随着多道程序技术而出现的。因此,操作系统和程序并发是一起诞生的。
  2. 单核CPU同一时刻只能执行一个程序,各个程序只能并发的执行。多核CPU同一时刻可以同时执行多个程序,多个程序可以并行的执行。

(2)共享:即资源共享,是指系统中地资源可供内存中多个并发执行地进程共同使用。

  • 两种资源共享方式:互斥共享方式与同时共享方式

  • 互斥共享方式:系统中的某些资源,虽然可以提供给多个进程使用,但一个时间段内只允许一个进程访问该资源。

  • 同时共享方式:系统中的某些资源,允许一个时间段内由多个进程同时对它们进行访问。所谓的同时往往是宏观上的,而在微观上,这些进程可能是交替地对该资源进行访问的(即分时共享)。

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

  • 并发和共享的关系
    抽时间整理了一下操作系统的学习笔记_第8张图片
并发和共享是两个最基本的特征,二者互为存在条件

(3)虚拟:是指把一个物理上的实体变为若干个逻辑上的对应物。物理实体(前者)是实际存在的,而逻辑上对应物(后者)是用户感受到的。
(4)异步:指多道程序环境下,允许多个程序并发执行,但由于资源有限,进程的执行不是一贯到底的,而是走走停停,以不可预知的速度向前推进,这就是进程的异步性。
抽时间整理了一下操作系统的学习笔记_第9张图片
小结:
抽时间整理了一下操作系统的学习笔记_第10张图片

3. 操作系统的运行机制

抽时间整理了一下操作系统的学习笔记_第11张图片
程序是如何运行的:
在这里插入图片描述
注意:指令就是处理器(CPU)能识别,执行的最基本命令。

程序运行的过程其实就是CPU执行一条一条的机器指令的过程
内核是操作系统最重要最核心的部分,也是最接近硬件的部分
  • 特权指令与非特权指令
  • 应用程序只能使用非特权指令,如:加法指令,减法指令等。
    操作系统内核作为管理者,有时会让CPU执行一些特权指令,如:内存清零指令。

在CPU设计和生产的时候划分了特权指令和非特权指令,因此CPU执行一条指令前就能判断出其类型。

内核态与用户态
CPU既然能判断出指令类型,但是它怎么区分此时正在运行的是内核程序或者是应用程序呢?

其实,CPU有两种状态,即内核态和用户态

  • 处于内核态时,说明此时正在运行的是内核程序,此时可以执行特权指令
  • 处于用户态时,说明此时正在运行的是应用程序,此时只能执行非特权指令

CPU中有一个寄存器叫程序状态字寄存器(PSW),其中有个二进制位,1表示内核态,0表示用户态。
抽时间整理了一下操作系统的学习笔记_第12张图片
  内核程序在合适的时候主动让出CPU,从核心态切换到用户态,即将让应用程序在CPU上运行。一旦CPU处于用户态时,我们的应用程序将会在此用户态下运行,此时CPU会执行应用程序中一条又一条的指令。但是如果此时在应用程序中恶意植入了一条特权指令,那么此时CPU当执行这条特权指令时,会检查自己的PSW,发现自己依然处于用户态却要执行这条特权指令,那么这个非法事件会引发一个中断信号发送给CPU,使得CPU强行从用户态转成核心态,并且CPU会拒绝执行该特权指令以及暂停执行后面的其他指令。转而CPU会执行一个处理中断信号的内核程序。
  换句话说,在发生中断信号之后,中断使操作系统内核再次夺回CPU的控制权,从用户态再次切换到核心态,操作系统会对引发中断的事件进行处理,处理完了再把CPU使用权交给别的应用程序。

  1. 当操作系统从内核态切换到用户态时:
    在这里插入图片描述
  2. 当操作系统从用户态切换到内核态时:
    在这里插入图片描述
    从用户态切换到内核态的前提是由中断引发的,除了非法使用特权指令之外,还有许多事件会触发中断信号。一个共性是,但凡需要操作系统介入的工作地方,都会触发中断信号。

小结:
抽时间整理了一下操作系统的学习笔记_第13张图片

4. 操作系统的中断与异常

抽时间整理了一下操作系统的学习笔记_第14张图片
我们知道在CPU上会运行两种程序,一种是操作系统的内核程序,一种是应用程序。内核程序是整个系统的管理者,在计算机启动时,CPU处于内核态,只是在合适的情况下,操作系统内核会把CPU的使用权主动让给应用程序。一个应用程序在上CPU运行之后,它就会一直运行下去,除非发送中断。

(1)中断的作用

中断是让操作系统内核夺回CPU使用权的唯一途径,使CPU由用户态变为内核态。

  • 那么问题来了,如果没有中断机制,那么一旦应用程序上CPU运行,CPU就会一直运行这个应用程序。如果CPU一直运行同一个应用程序,将如何实现多道程序并发这个事情呢?
    在这里插入图片描述

(2)中断的类型

中断分为内中断与外中断

  • 内中断:与当前执行的指令有关,中断信号来源于 CPU内部
  • 外中断:与当前执行的指令无关,中断信号来源于 CPU外部

我们来看内中断的例子:

  1. 试图在用户态下执行特权指令
    抽时间整理了一下操作系统的学习笔记_第15张图片
  2. 执行除法指令时发现除数为0
    总之,若当前执行的指令是非法的,或执行指令的参数是非法的,那么就会引发一个中断信号。
  3. 有时候应用程序想请求操作系统内核的服务,此时会执行一条特殊的指令——陷入指令,该指令会引发一个内部中断信号。

执行陷入指令,意味着应用程序主动地将CPU控制权还给操作系统内核,系统调用就是通过陷入指令完成的

陷入指令是一种特殊的指令不是特权指令

我们再来看外中断的例子:

  1. 时钟中断——由时钟部件发来的中断信号
    抽时间整理了一下操作系统的学习笔记_第16张图片系统中想要并发的运行两个应用程序,首先应用程序1运行在用户态,CPU执行其指令,假如当CPU执行两条指令后,时钟部件检测已经执行过了50ms,于是时钟部件会给CPU发送一个中断信号,此时CPU会暂停执行应用程序1,转而去执行处理时钟中断的内核程序,去处理这个中断信号。
    抽时间整理了一下操作系统的学习笔记_第17张图片
    此时CPU由用户态转为内核态,在处理中断信号的内核程序中,操作系统内核发现应用程序1已经用了50ms,为了公平起见,操作系统内核决定接下来让另一个应用程序2上CPU运行。
    CPU又从内核态转为用户态,CPU执行应用程序2的指令,同样的,时钟部件检测已经过了50ms,于是时钟部件再次会给CPU发送一个中断信号,此时CPU又会暂停执行应用程序2,转而去执行处理时钟中断的内核程序。
    在处理中断信号的内核程序中,操作系统内核发现应用程序2已经用了50ms,为了公平起见,操作系统内核决定接下来又让应用程序1上CPU运行,于是将CPU的使用权让给应用程序1,然后应用程序1就会执行它之后的未执行的指令,依次往复。
  2. I/O中断——由输入/输出设备发来的中断信号
    每一条指令执行结束时,CPU都会例行检查是否有外部中断信号
    抽时间整理了一下操作系统的学习笔记_第18张图片

(3)中断机制的基本原理

不同的中断信号,需要用不同的中断处理程序来处理

当CPU检测到中断信号后,会根据中断信号的类型去查询中断向量表,以此来找到相应的中断处理程序在内存中的存放位置。
抽时间整理了一下操作系统的学习笔记_第19张图片
小结:
抽时间整理了一下操作系统的学习笔记_第20张图片

5. 进程的自述

程序:是静态的,就是个存放在磁盘里的可执行文件,就是一系列的指令集合。比如在Windows中就是以后缀为.exe的可执行文件

进程:是动态的,是程序的一次执行过程

同一个程序多次执行会对应多个进程

进程的组成部分——(PCB)
那么既然操作系统是这些进程的管理者,它要怎么区分各个进程呢?

  • 当进程被创建时,操作系统会为该进程分配一个唯一的,不重复的身份证号(PID)
  • 操作系统要记录PID,进程所属用户ID(UID),操作系统可以根据PID,UID这些基本的进程描述信息,让操作系统区分各个进程。
  • 操作系统要记录给进程分配了哪些资源(如:分配了多少内存,正在使用哪些I/O设备,正在使用哪些文件),这些信息可以用于实现操作系统对资源的管理。
  • 操作系统要记录进程的运行情况(如:CPU使用时间,磁盘使用情况,网络流量使用情况等),这些信息可以实现操作系统对进程的控制,调度。

那么既然操作系统要记录这么多信息,那该如何整理呢?

  • 其实这些信息都被保存在一个数据结构PCB中,即进程控制块。总之,操作系统需要对各个并发运行的进程进行管理,但凡管理时所需要的信息,都会被放在PCB中。
    抽时间整理了一下操作系统的学习笔记_第21张图片
    PCB是进程存在的唯一标志,当进程被创建时,操作系统为其创建PCB,当进程结束时,会收回其PCB。

进程的组成部分:PCB,程序段,数据段
抽时间整理了一下操作系统的学习笔记_第22张图片

这里需要明确的是PCB是给操作系统用的,而程序段,数据段是给进程自己用的。

什么是程序的运行?

  1. 我们知道程序在运行之前,都需要通过编译器将代码“翻译”成二进制的机器指令,一条高级语言的代码翻译过来可能会对应多条机器指令。那么程序运行的过程其实就是CPU执行一条一条的机器指令的过程。
  2. 当我们写完一个程序之后,经过编译链接等一系列的步骤,最终会形成一个后缀为.exe的可执行文件,这个可执行文件一直是存放在硬盘当中的,在系统运行这个可执行文件前需要把程序放入内存中,同时操作系统会为其创建相应的PCB,以及一些程序段也会调入内存中,我们知道程序段中包含了一条一条的指令,我们的CPU就是从内存中取出这些指令。此外,程序是基于代码的,那代码的一些运算结果同样需要被调用。换句话说,数据段也要被调入到内存之中,数据段包含了运行过程中产生的,需要使用的各种数据,比如我们定义了某些变量,就是包含在数据段里的。
    抽时间整理了一下操作系统的学习笔记_第23张图片
    总结:一个进程的实体(进程映像)是由PCB,程序段,数据段组成的

进程的深度解读:
抽时间整理了一下操作系统的学习笔记_第24张图片

PCB是进程存在的唯一标志!

进程的特征:
抽时间整理了一下操作系统的学习笔记_第25张图片
注意:
(1)进程是动态的,动态性是进程最基本的特征
(2)异步性会导致并发程序执行结果的不确定性

小结:
抽时间整理了一下操作系统的学习笔记_第26张图片

6. 进程的状态与转换

抽时间整理了一下操作系统的学习笔记_第27张图片
进程的状态——创建态,就绪态
(1)进程正在被创建时,它的状态是创建态,在这个阶段操作系统会为进程分配资源,初始化PCB。
(2)当进程创建完成后,便进入就绪态,处于就绪态的进程已经具备运行条件,但由于没有空闲CPU,就暂时不能运行。
抽时间整理了一下操作系统的学习笔记_第28张图片
进程的状态——运行态
在一个进程中可能会有很多个进程都处于就绪态,当CPU空闲时,操作系统就会选择一个就绪进程,让它上处理机运行。
抽时间整理了一下操作系统的学习笔记_第29张图片
如果一个进程此时在CPU上运行,那么这个进程处于运行态。换句话说,此时CPU会执行该进程对应的程序(执行指令序列)。

进程的状态——阻塞态
在进程运行的过程中,可能会请求等待某个事件的发生,如等待某种系统资源的分配,或者等待其他进程的响应。
在这个事件发生之前,进程无法继续往下执行,此时操作系统会让这个进程下CPU,并让它进入阻塞态。当CPU空闲时,又会选择另一个就绪态进程上CPU运行。

进程的状态——终止态
假设此时运行在CPU上的进程1已经运行结束了,在运行结束时会发出一个(exit)的系统调用,请求操作系统终止该进程。
抽时间整理了一下操作系统的学习笔记_第30张图片
此时该进程会进入终止态,操作系统会让该进程下CPU,并回收内存空间等资源,最后还是要回收该进程的CPU。当终止进程的工作完成之后,这个进程就彻底消失了。
抽时间整理了一下操作系统的学习笔记_第31张图片
进程状态的转换(图解):
抽时间整理了一下操作系统的学习笔记_第32张图片
进程的状态:
抽时间整理了一下操作系统的学习笔记_第33张图片
进程PCB中,会有一个变量state来表示进程的当前状态。如:1表示创建态,2表示就绪态,3表示运行态。为了对同一个状态下的各个进程进行统一的管理,操作系统会将各个进程的PCB组织起来。

  • 那么如何将各个进程的PCB组织起来?

链接方式与索引方式

  1. 链接方式
    (1)执行指针——指向当前处于运行状态(执行态)的进程
    (2)就绪队列指针——指向当前处于就绪状态的进程
    (3)阻塞队列指针——指向当前处于阻塞态的进程

抽时间整理了一下操作系统的学习笔记_第34张图片

  1. 索引方式
    抽时间整理了一下操作系统的学习笔记_第35张图片
    抽时间整理了一下操作系统的学习笔记_第36张图片

小结:
抽时间整理了一下操作系统的学习笔记_第37张图片

7. 进程控制及原语

抽时间整理了一下操作系统的学习笔记_第38张图片
(1)什么是进程控制?
进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程,撤销已有进程,实现进程状态转换等功能。

简单的说:进程控制就是要实现进程状态转换

抽时间整理了一下操作系统的学习笔记_第39张图片
(2)如何实现进程控制?
进程实现进程不同状态的转换是需要用“原语”来实现的
抽时间整理了一下操作系统的学习笔记_第40张图片

  • 原语是一种特殊的程序,它的执行具有原子性。也就是说,这段程序的运行必须一气呵成,不可中断。

那么思考一个问题,为什么进程控制(状态转换)的过程要一气呵成?
抽时间整理了一下操作系统的学习笔记_第41张图片
我们假设此时进程2等待的事件发生,则操作系统中,负责进程控制的内核程序至少做这样两件事:
(1)将PCB2的(state)设为1
(2)将PCB2从阻塞队列放到就绪队列

如果此时我们已经将PCB2的(state)设为1,如图:
抽时间整理了一下操作系统的学习笔记_第42张图片
但是恰好此时收到了中断信号,那么PCB2的(state)=1本来表示就绪状态却被放在阻塞队列里,这时如果不能一气呵成,就有可能导致操作系统中的某些关键数据结构信息不统一的情况,这会影响操作系统进行别的管理工作。所以这就是为什么进程状态的转换必须一气呵成!

(3)如何实现原语的原子性?
原语的执行具有原子性,即执行过程只能一气呵成,期间不允许被中断。可以用关中断指令和开中断指令这两个特权指令实现原子性。

CPU正常情况下运行:
抽时间整理了一下操作系统的学习笔记_第43张图片
CPU执行了关中断与开中断指令:
抽时间整理了一下操作系统的学习笔记_第44张图片
思考:如果这两个特权指令允许用户程序使用的话,会发生什么情况?

  • 这样就意味着我们可以在程序的开头植入一个关中断指令,然后在程序的末尾植入一个开中断指令,如此只要该程序上CPU运行,那程序就可以一直霸占CPU,显然这是不应该发生的。

所以开中断与关中断是两条特权指令

(4)进程控制相关的原语

  1. 进程的创建
    抽时间整理了一下操作系统的学习笔记_第45张图片
  2. 进程的终止
    抽时间整理了一下操作系统的学习笔记_第46张图片
  3. 进程的阻塞和唤醒
    抽时间整理了一下操作系统的学习笔记_第47张图片
  4. 进程的切换
    抽时间整理了一下操作系统的学习笔记_第48张图片
    总结:无论哪个进程控制原语,要做的无非是三件事情:
    1.更新PCB中的信息,修改进程状态(state)保存和恢复运行环境
    2.将PCB插入合适的队列
    3.分配和回收资源

小结:
抽时间整理了一下操作系统的学习笔记_第49张图片

8. 线程与多线程模型

抽时间整理了一下操作系统的学习笔记_第50张图片
在没有引入进程之前,系统中的各个程序只能串行执行,换句话说我们如果想要一边听音乐,一边玩QQ是不可以的。在引入进程之后,我们可以一边听音乐,一边玩QQ。但是问题来了,QQ中许多的功能,比如视频,文字聊天,传送文件等,可我们知道进程是程序的一次执行,那么这些功能显然不可能是由一个程序顺序处理就能实现的。
抽时间整理了一下操作系统的学习笔记_第51张图片
因此我们引入了线程的概念:
抽时间整理了一下操作系统的学习笔记_第52张图片
传统的进程是程序执行流的最小单位,但在引入线程后,线程成为了程序执行流的最小单位。

同样,我们可以把线程理解为轻量级的进程

引入线程之后,不仅是进程之间可以并发,进程内的各线程之间也可以并发,进一步提升了系统的并发度,使得一个进程内也可以并发处理各种任务,这时进程只作为除CPU之外的系统资源的分配单元

引入线程机制后,有什么变化?
抽时间整理了一下操作系统的学习笔记_第53张图片
线程的属性:
抽时间整理了一下操作系统的学习笔记_第54张图片
线程的实现方式与多线程模型
抽时间整理了一下操作系统的学习笔记_第55张图片
(1)用户级线程
抽时间整理了一下操作系统的学习笔记_第56张图片
很多编程语言提供了强大的线程库,可以实现线程的创建,销毁,调度等功能。

  • 那么线程的管理工作由谁来完成的?

线程的管理工作由应用程序提供的线程库来完成的,并不是由操作系统来完成的。

  • 线程切换是否需要CPU从用户态转换为内核态?

其实线程切换是由应用程序的线程库自己完成的,在用户态下就可以完成线程切换,不需要操作系统的切换。

  • 操作系统是否能意识到用户级线程的存在?

不能,只有用户才能感知到用户级线程的存在。

用户级线程的优缺点:

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

(2)内核级线程
内核级线程,由操作系统支持的线程
抽时间整理了一下操作系统的学习笔记_第57张图片
注意:内核级线程与用户级线程不同

  1. 内核级线程的管理工具由操作系统内核完成
  2. 线程调度,切换等工作都由内核负责,因此内核级线程的切换必须需要在核心态下才能完成
  3. 操作系统会为每个内核级线程建立相应的TCB(线程控制块),通过TCB对线程进行管理。内核级线程就是从操作系统内核视角看能看到的线程。

内核级线程的优缺点:

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

多线程模型
之前我们讨论了用户级线程与内核级线程的优缺点,那么我们是否可以将这两种线程方式结合起来呢?
(1)一对一模型
抽时间整理了一下操作系统的学习笔记_第58张图片
(2)多对一模型
抽时间整理了一下操作系统的学习笔记_第59张图片
(3)多对多模型
抽时间整理了一下操作系统的学习笔记_第60张图片

总结:内核级线程与用户级线程
(1)用户级线程是代码逻辑的载体
(2)内核级线程是运行机会的载体
(3)内核级线程才是处理机分配的单位
(4)一段代码逻辑只有获得了运行机会才能被CPU执行

内核级线程中可以运行任意一个有映射关系的用户级线程代码,只有两个内核级线程中正在运行的代码逻辑都阻塞时,这个进程才会阻塞。

小结:
抽时间整理了一下操作系统的学习笔记_第61张图片

9. 处理机调度

抽时间整理了一下操作系统的学习笔记_第62张图片
调度的基本原理:
当我们去银行取钱时,我们或许需要排队等待,作为普通客户,一般银行遵循着先到先服务的顺序。但是如果有VIP客户的话,他们未必需要排队就可以优先被服务。
抽时间整理了一下操作系统的学习笔记_第63张图片
当有一堆任务要处理,但由于资源有限,任务没法同时处理这就需要确定某种规则来决定处理这些任务的顺序,这就是调度研究的问题。

高级调度

作业:一个具体的任务

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

但是问题来了,我们的内存空间有限,有时无法将用户提交的作业全部放入内存,那该这么办呢?

  • 所谓高级调度(作业调度),是按一定的原则从外存的作业后备队列中挑选一个作业调入内存,并创建进程。每个作业只调入一次,调出一次。作业调入时会建立PCB,调出时才撤销PCB。

低级调度

  • 指按照某种策略从就绪队列中选择一个进程,将处理机分配给它。
  • 进程调度是操作系统中最基本的一种调度,在一般的操作系统中都必须配置进程调度。

抽时间整理了一下操作系统的学习笔记_第64张图片
中级调度
内存不够时,可将某些进程的数据调出外存,等内存空闲或者进程需要运行时再重新调入内存。暂时调到外存等待的进程状态为挂起状态,被挂起的进程PCB会被组织成挂起队列。
抽时间整理了一下操作系统的学习笔记_第65张图片

  • 所谓中级调度(内存调度)是指按照某种策略决定将哪个处于挂起状态的进程重新调入内存。
  • 一个进程可能会被多次调出,调入内存,因此中级调度发生的频率要比高级调度更高。

挂起状态
抽时间整理了一下操作系统的学习笔记_第66张图片
抽时间整理了一下操作系统的学习笔记_第67张图片
三层调度的联系与对比:
抽时间整理了一下操作系统的学习笔记_第68张图片
小结:
抽时间整理了一下操作系统的学习笔记_第69张图片

10. 进程调度的时机

抽时间整理了一下操作系统的学习笔记_第70张图片
进程调度的时机
我们知道进程调度(低级调度),就是按照某种算法从就绪队列中选择一个进程为其分配处理机。那什么时候进行进程调度与切换的情况?
(1)当前运行的进程主动放弃处理机
(2)当前运行的进程被动放弃处理机

抽时间整理了一下操作系统的学习笔记_第71张图片

  • 进程在操作系统内核程序临界区中不能进行调度与切换
  • 进程处于临界区时不能进行处理机调度

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

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

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

举两个例子:
(1)内核程序临界区访问的临界资源需要尽快的释放,不可以进行进程调度和切换
在这里插入图片描述
抽时间整理了一下操作系统的学习笔记_第72张图片
(2)普通临界区访问的临界资源时可以进行进程调度和切换
抽时间整理了一下操作系统的学习笔记_第73张图片
进程调度的方式

  1. 非剥夺调度方式,又称非抢占式。即只允许进程主动放弃处理机。在运行过程中即便有更紧迫的任务到达,当前进程依然会继续使用处理机,直到该进程终于或主动要求进入阻塞状态。
  2. 剥夺调度方式,又称抢占方式。当一个进程正在处理机上执行时,如果有一个更重要或更紧迫的进程需要使用处理机,则立即暂停正在执行的进程,将处理机分配给更重要紧迫的那个进程。
  • 非剥夺调度方式实现简单,系统开销小但是无法及时处理紧急任务,适合于早期的批处理系统。

  • 剥夺调度方式可以优先处理更紧急的进程,也可以实现让各进程按时间片轮流执行的功能,适合于分时操作系统,实时操作系统。

进程的切换与过程

  • 狭义的进程调度指的是从就绪队列中选中一个要运行的进程
  • 广义的进程调度包含了选择一个进程和进程切换两个步骤

进程切换是指一个进程让出处理机,由另一个进程占用处理机的过程。
抽时间整理了一下操作系统的学习笔记_第74张图片
小结:
抽时间整理了一下操作系统的学习笔记_第75张图片

11. 调度算法的评价指标

抽时间整理了一下操作系统的学习笔记_第76张图片
CPU的利用率

CPU利用率:是指CPU忙碌的时间占总时间的比例
在这里插入图片描述
来道例题:
抽时间整理了一下操作系统的学习笔记_第77张图片
系统吞吐量

系统吞吐量是指:单位时间内完成作业的数量
在这里插入图片描述
来道例题:
在这里插入图片描述
周转时间

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

  • 周转时间包括四个部分:
  1. 作业在外存后备队列上等待作业调度(高级调度)的时间
  2. 进程在就绪队列等待进程调度(低级调度)的时间
  3. 进程在CPU上执行的时间
  4. 进程等待I/O操作完成的时间

周转时间与平均周转时间
在这里插入图片描述
带权周转时间

对于周转时间相同的两个作业,实际运行时间长的作业在相同时间内被服务的时间更多,带权周转时间更小,用户满意度更高。
在这里插入图片描述
对于实际运行时间相同的两个作业,周转时间短的带权周转时间更小,用户满意度更高。

注意:
带权周转时间必然大于(等于)1
带权周转时间与周转时间都是越小越好

平均带权周转时间
在这里插入图片描述
等待时间

等待时间:指进程(作业)处于等待处理机状态时间之和,等待时间越长,用户满意度越低。
抽时间整理了一下操作系统的学习笔记_第78张图片
一个作业总共需要被CPU服务多久,被I/O设备服务多久一般是确定不变的,因此调度算法其实只会影响作业/进程的等待时间。

响应时间

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

小结:
抽时间整理了一下操作系统的学习笔记_第79张图片

12. 调度算法思想及规则(上)

抽时间整理了一下操作系统的学习笔记_第80张图片
一. 先来先服务调度算法(FCFS)

(1)算法思想:

  • 主要是从公平的角度考虑(类似于我们生活中排队买东西的例子)

(2)算法规则:

  • 按照作业/进程到达的先后顺序进行服务
  • 按照到达的先后顺序调度,事实上就是等待时间越久的越优先得到服务

(3)用于作业(进程)调度:

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

例题:
抽时间整理了一下操作系统的学习笔记_第81张图片
(4)先来先服务调度算法的优缺点:

  • 优点:公平,算法实现简单
  • 缺点:排在长作业(进程)后面的短作业需要等待很长时间,带权周转时间很大,对短作业来说用户体验不好
  • 即先来先服务调度算法对长作业有利,对短作业不利
  • 先来先服务调度算法是不会导致饥饿的

(5)先来先服务调度算法概述:
抽时间整理了一下操作系统的学习笔记_第82张图片
二. 短作业优先调度算法(SJF)

(1)算法思想:

  • 追求最少的平均等待时间,最少的平均周转时间,最少的平均带权周转时间

(2)算法规则:

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

(3)用于作业(进程)调度:

  • 即可用于作业调度,也可用于进程调度
  • 用于进程调度时称为”短进程优先算法(SPF)

(4)是否可抢占:

  • SJF和SPF是非抢占式的算法
  • 但是也有抢占式的版本——最短剩余时间优先算法(SRTN)

例题:
使用非抢占式的短作业优先调度算法SJF
抽时间整理了一下操作系统的学习笔记_第83张图片
使用抢占式的短作业优先调度算法SRTN
抽时间整理了一下操作系统的学习笔记_第84张图片
抽时间整理了一下操作系统的学习笔记_第85张图片
使用短作业优先算法需要注意:
抽时间整理了一下操作系统的学习笔记_第86张图片
(5)短作业优先调度算法的优缺点:

  • 优点:最短的平均等待时间,平均周转时间
  • 缺点:对短作业有利,对长作业不利。可能产生饥饿现象。

(6)短作业优先调度算法概述:
抽时间整理了一下操作系统的学习笔记_第87张图片
对FCFS和SJF两种算法的思考:

FCFS算法是在每次调度的时候选择一个等待时间最长的作业(进程)为其服务。但是没有考虑到作业的运行时间,因此导致了对短作业不友好的问题。

SJF算法是选择一个执行时间最短的作业为其服务。但是又完全不考虑各个作业的等待时间,因此导致了对长作业不友好的问题,甚至还会造成饥饿问题。

那么,我们能不能设计一个算法,即考虑到各个作业的等待时间,也能兼顾运行时间?

三. 高响应比优先调度算法(HRRN)

(1)算法思想

  • 要综合考虑作业/进程的等待时间和要求服务的时间

(2)算法规则

  • 在每次调度时先计算各个作业(进程)的响应比,选择响应比最高的作业(进程)为其服务
    在这里插入图片描述

(3)用于作业(进程)调度

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

(4)是否可抢占?

  • 非抢占式的算法。因此只有当前运行的作业/进程主动放弃处理机时,才需要调度,才需要计算响应比

(5)高响应比优先算法优缺点

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

例题:
抽时间整理了一下操作系统的学习笔记_第88张图片
(6)高响应比优先算法概述
抽时间整理了一下操作系统的学习笔记_第89张图片
小结:
抽时间整理了一下操作系统的学习笔记_第90张图片

13. 调度算法思想及规则(下)

抽时间整理了一下操作系统的学习笔记_第91张图片
四. 时间片轮转调度算法(RR)

(1)算法思想

  • 公平的,轮流地为各个进程服务,让每个进程在一定时间间隔内都可以得到响应。

(2)算法规则

  • 按照各进程到达就绪队列的顺序,轮转让各个进程执行一个时间片。若进程未在一个时间片内执行完,则剥夺处理机,将进程重新放到就绪队列队尾重新排队。

(3)用于作业(进程)调度

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

(4)是否可抢占?

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

(5)时间片轮转调度算法的优缺点

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

例题:
抽时间整理了一下操作系统的学习笔记_第92张图片
1.当时间片大小为2时:抽时间整理了一下操作系统的学习笔记_第93张图片
时刻流程图:
(1)0-5时刻(2)6-11时刻(3)12-16时刻
抽时间整理了一下操作系统的学习笔记_第94张图片
2.当时间片大小为5时:
抽时间整理了一下操作系统的学习笔记_第95张图片
同一道例题,我们对比用先来先服务调度算法
抽时间整理了一下操作系统的学习笔记_第96张图片

  • 我们发现:如果时间片太大,使得每个进程都可以在一个时间片内就完成,则时间片轮转调度算法退化为先来先服务调度算法,并且会增大进程响应时间。因此时间片不能太大。
  • 如果时间片太小,会导致进程切换过于频繁,系统会花大量的时间来处理进程切换,从而导致实际用于进程执行的时间比例减少。可见时间片也不能太小。

(6)时间片轮转调度算法概述
抽时间整理了一下操作系统的学习笔记_第97张图片
五. 优先级调度算法

(1)算法思想

  • 随着计算机的发展,特别是实时操作系统的出现,越来越多的应用场景需要根据任务的紧急程度来决定处理顺序

(2)算法规则

  • 每个作业(进程)有各自的优先级,调度时选择优先级最高的作业/进程

(3)用于作业(进程)调度

  • 既可以用与作业调度,也可以用于进程调度。甚至还会用于I/O调度。

(4)是否可抢占?

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

(5)优先级调度算法的优缺点

  • 优点:用优先级区分紧急程度,重要程度,适合于实时操作系统。可灵活的调整对各种作业(进程)的偏好程度。
  • 缺点:若源源不断地有高优先级进程到来,则可能导致饥饿。

例题:
抽时间整理了一下操作系统的学习笔记_第98张图片
抽时间整理了一下操作系统的学习笔记_第99张图片
抽时间整理了一下操作系统的学习笔记_第100张图片
(6)优先级调度算法概述
抽时间整理了一下操作系统的学习笔记_第101张图片
思考:
抽时间整理了一下操作系统的学习笔记_第102张图片
六. 多级反馈队列调度算法(简述)
抽时间整理了一下操作系统的学习笔记_第103张图片
例题:
在这里插入图片描述
小结:
抽时间整理了一下操作系统的学习笔记_第104张图片

14. 进程同步与进程互斥

抽时间整理了一下操作系统的学习笔记_第105张图片
什么是进程同步?

我们来看一个管道通信的例子:
抽时间整理了一下操作系统的学习笔记_第106张图片

异步性是指:各并发执行的进程以各自独立的,不可预知的速度向前推进

  • 同步亦称直接制约关系,它是指为完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调它们的工作次序而产生的制约关系。
  • 进程间的直接制约关系就是源于它们之间的相互合作。

什么是进程互斥?
进程的并发需要共享的支持,各个并发执行的进程不可避免地需要共享一些系统资源。
抽时间整理了一下操作系统的学习笔记_第107张图片
对临界资源地互斥访问,可以在逻辑上分为如下四个部分:
1.进入区 2.临界区 3.退出区 4.剩余区

注意:
临界区是进程中访问临界资源的代码段
进入区和退出区是负责实现互斥的代码段

为了实现对临界资源的互斥访问,同时保证系统整体性能,需要遵循以下原则:
抽时间整理了一下操作系统的学习笔记_第108张图片
小结:
抽时间整理了一下操作系统的学习笔记_第109张图片

15. 生产者消费者问题

问题描述:

系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用。(这里的产品理解为某种数据)

1.整理思路
(1)生产者,消费者共享一个初始为空,大小为n的缓冲区。
如图:缓冲区的大小为5
抽时间整理了一下操作系统的学习笔记_第110张图片
只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待。

(2)如果缓冲区已经满了,生产者进程依然向缓冲区里写数据,此时生产者进程必须等待,当缓冲区中有空的时候才能向缓冲区里写数据。
抽时间整理了一下操作系统的学习笔记_第111张图片
(3)只有缓冲区不空时,消费者才能从中取出产品,否则必须等待。
抽时间整理了一下操作系统的学习笔记_第112张图片
(4)缓冲区是临界资源,各进程必须互斥地访问。
抽时间整理了一下操作系统的学习笔记_第113张图片
2.关系分析
抽时间整理了一下操作系统的学习笔记_第114张图片

  • 当生产者进程向缓冲区放入一个产品后,此时信号量需要执行一个V操作
  • 当消费者进程在缓冲区取走一个产品前,此时信号量需要执行一个P操作

3.代码实现
抽时间整理了一下操作系统的学习笔记_第115张图片
实现两对同步关系:
抽时间整理了一下操作系统的学习笔记_第116张图片

因为缓冲区是临界资源,各进程必须互斥地访问,所以我们还需要设置互斥信号量

抽时间整理了一下操作系统的学习笔记_第117张图片
4. 代码分析
执行V操作的进程会唤醒对应执行P操作的进程:
抽时间整理了一下操作系统的学习笔记_第118张图片
思考:能否改变相邻P,V操作的顺序?
抽时间整理了一下操作系统的学习笔记_第119张图片
小结:
抽时间整理了一下操作系统的学习笔记_第120张图片

16. 读者与写者问题

问题描述:

有读者和写者两组并发进程,共享一个文件,当两个或两个以上的读进程同时访问共享数据时不会产生副作用,但若某个写进程和其他进程(读进程或写进程)同时访问共享数据时则可能导致不一致的错误。

因此要求:
(1)允许多个读者可以同时对文件执行读操作
(2)只允许一个写者往文件中写信息
(3)任意写者在完成写操作之前不允许其他读者或写者工作
(4)写者执行写操作前,应让己有的读者和写者全部退出

注意:

  • 与消费者进程不同,读者进程在读数据后并不会将数据清空,并不会改变数据。因此多个读者可同时访问共享数据。
  • 读进程与写进程同时共享数据,可能导致读出的数据不一致的问题。

抽时间整理了一下操作系统的学习笔记_第121张图片
如果两个写进程同时共享数据,可能导致数据错误覆盖的问题

1.关系分析
在这里插入图片描述
2.如何实现
抽时间整理了一下操作系统的学习笔记_第122张图片
潜在的问题:只要有读进程还在读,写进程就要一直阻塞等待,可能饿死。因此,这种算法中,读进程是优先的。

那么如何解决写进程饿死的状态呢,我们来看代码:
抽时间整理了一下操作系统的学习笔记_第123张图片
结论:在这种算法中,连续进入的多个读者可以同时读文件。写者和其他进程不能同时访问文件,写者不会饥饿,但也并不会是真正的写优先,而是相对公平的先来先服务原则。

读者写者问题为我们解决复杂的互斥问题提供了一个参考思路。其核心思想在于设置了一个计数器(count)用来记录当前正在访问共享文件的读进程数。我们可以用(count)的值来判断当前进入的进程是否是第一个/最后一个读进程,从而做出不同的处理。
另外,对(count)变量的检查和赋值不能一气呵成导致了一些错误,如果需要实现一气呵成,自然应该想到用互斥信号量。

17. 哲学家进餐问题

问题描述:

一个圆桌上坐着5名哲学家,每两个哲学家之间的桌子上摆一根筷子,桌子的中间是一碗米饭。哲学家们倾注毕生的精力用于思考和进餐,哲学家在思考时,并不影响他人。只有当哲学家饥饿时,才试图拿起左右两根筷子(一根一根地拿起)。如果筷子已在他人手上,则需要等待。饥饿的哲学家只有同时拿起两根筷子才可以开始进餐,当进餐完毕后,放下筷子继续思考。
抽时间整理了一下操作系统的学习笔记_第124张图片

1.关系分析

  • 系统中有5个哲学家进程,5位哲学家与左右邻居对其中间筷子的访问是互斥关系。

2.整理思路

  • 哲学家问题只有互斥关系,但与之前遇到的问题不是的是,每个哲学家进程需要同时持有两个临界资源才能开始吃饭。如何避免临界资源分配不当造成的死锁现象,是哲学家问题的精髓。

3.解决方案

  • 信号量设置。定义互斥信号量数组chopstick[5]={1,1,1,1,1}用于实现对5个筷子的互斥访问。并对哲学家按0-4编号,哲学家i左边的筷子编号为i,右边的筷子编号为(i+1)%5,每个哲学家吃饭前依次拿起左,右两支筷子。
    抽时间整理了一下操作系统的学习笔记_第125张图片
  • 但是如果5个哲学家并发地拿起了自己左手边的筷子,那么会出现的问题是每位哲学家循环等待右边的人放下筷子(阻塞),发生死锁。
    抽时间整理了一下操作系统的学习笔记_第126张图片

如何防止死锁的发生呢?
抽时间整理了一下操作系统的学习笔记_第127张图片

4.解决思路
(1)最多允许四个哲学家同时进餐
(2)在每个哲学家进餐之前先判断哲学家是奇数还是偶数

当然,我们还可以这样解决死锁问题:

我们可以规定仅当一个哲学家左右两支筷子都可用时才允许他抓起筷子

抽时间整理了一下操作系统的学习笔记_第128张图片
我们用信号量mutex,保证了哲学家拿筷子这件事必须互斥的进行。即使一个哲学家在拿筷子拿到一半时被阻塞,也不会有别的哲学家会继续尝试拿筷子。这样的话,当前正在吃饭的哲学家放下筷子后,被阻塞的哲学家就可以获得等待的筷子了。

18. 死锁的自述

抽时间整理了一下操作系统的学习笔记_第129张图片
什么是死锁?
(1)我们来看一个哲学家进餐的问题
抽时间整理了一下操作系统的学习笔记_第130张图片
每位哲学家都在等待自己右边的人放下筷子,这些哲学家进程都因为等待筷子资源而被阻塞,即发生死锁。

那么在并发环境下,各进程因竞争资源而造成的一种相互等待对方手里的资源,导致各进程都被阻塞,都无法向前推进的现象,就是死锁。

死锁,饥饿,死循环的区别:
抽时间整理了一下操作系统的学习笔记_第131张图片
死锁产生的必要条件:

产生死锁必须同时满足一下四个条件,只要其中任一条件不成立,死锁就不会发生

  1. 互斥条件
    只有对必须互斥使用的资源的争抢才会导致死锁(如哲学家的筷子,打印机设备)。像内存,扬声器这样可以同时让多个进程使用的资源是不会导致死锁的(因为进程不用阻塞等待这些资源)。

  2. 不剥夺条件
    进程所获得的资源在未使用完之前,不能由其他进程强行夺走,只能主动释放。

  3. 请求和保持条件
    进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源又被其他进程占有,此时请求进程被阻塞,但又对自己已有的资源保持不放。

  4. 循环等待条件
    存在一种进程资源的循环等待链,链中的每一个进程已获得的资源同时被下一个进程所请求。

注意:

  • 发生死锁时一定有循环等待,但是发生循环等待时未必死锁(循环等待是死锁的必要不充分条件)。
  • 如果同类资源大于1,则即使有循环等待,也未必发生死锁。但如果系统中每类资源都只有一个,那循环等待就是死锁的充分必要条件了。

什么时候会发生死锁?
抽时间整理了一下操作系统的学习笔记_第132张图片
总之,对不可剥夺资源的不合理分配,可能导致死锁

死锁的处理策略:
抽时间整理了一下操作系统的学习笔记_第133张图片
预防死锁:
抽时间整理了一下操作系统的学习笔记_第134张图片
小结:
抽时间整理了一下操作系统的学习笔记_第135张图片

你可能感兴趣的:(操作系统)