操作系统全套详解

想到之前学算法的时候,对于每一栏都喜欢自己写一篇文章,而操作系统如此重要,后续还有考研需要,我也准备写一篇操作系统的课程。以下内容提取自王道考研
第一天:
1、操作系统的概念
2、操作系统的特征
3、操作系统的发展和分类
4、操作系统的运行机制、体系结构
5、中断
6、系统调用
7、进程的定义、组成、组织方式、特征
8、进程的状态和转换
9、进程控制
10、进程通信
11、线程概念多线程模型
12、处理机调度的概念和层次
13、进程调度的时机和切换与过程调度方式
14、调度算法的评价指标
15、调度算法
16、进程同步、进程互斥
17、进程互斥的软件实现方法
18、进程互斥的硬件实现方法
19、信号量机制
20、用信号量机制来实现进程互斥、同步、前驱关系
21、生产者消费者问题
22、多生产者-多消费者
23、吸烟者问题
24、读者、写者问题
25、哲学家进餐问题
26、管程
27、死锁的概念
28、死锁的处理策略——预防死锁
29、死锁的处理策略——避免死锁(银行家算法)
30、死锁的处理策略——检测和解除
31、内存的基础知识
32、内存管理的概念
33、覆盖与交接
34、连续分配管理方式
35、动态分区分配算法
36、基本分页存储管理的基本概念
37、基本地址变化机构
38、具有快表的地址变换机构
39、两级页表
40、基本分段存储管理方式
41、段页式管理方式
42、虚拟内存的基本概念
43、请求分页管理方式
44、页面置换算法
45、页面分配策略
46、初始文件管理
47、文件的逻辑结构
48、文件目录
49、文件的物理结构(上)
50、文件的物理结构(下)
51、文件存储空间管理
52、文件的基本操作
53、文件共享
54、文件保护
55、文件系统的层次结构
56、磁盘的结构
57、磁盘调度算法
58、减少磁盘延迟时间的算法
59、磁盘的管理
60、I-O设备的概念和分类
61、I-O控制器
62、I-O控制方式
63、I-O软件层次结构
64、I-O核心子结构
65、假脱机技术
66、设备的分配和回收
67、缓冲区管理

操作系统的概念

基本分段存储管理方式

段页式管理方式

文件存储空间管理

文件的基本操作

减少磁盘延迟时间的算法

磁盘的管理

设备的分配和回收

缓冲区管理

在这里插入图片描述
操作系统的定义

在这里插入图片描述
操作系统的定义和目标
首先我们提出三个问题:
在这里插入图片描述

1、作为系统资源的管理者:

有4个功能:

  1. 处理机管理
  2. 存储器管理
  3. 文件管理
  4. 设备管理

dd

2、作为用户和计算机硬件之间的接口

接口主要分成3类:

  1. 命令接口:允许用户直接使用
  2. 程序接口:允许用户通过程序间接使用
  3. GUI:现代操作系统中最流行的图形用户接口
    其中命令接口和程序接口统称为用户接口

在这里插入图片描述

命令接口又分为联机命令接口脱机命令接口

联机命令接口

又成为交互式命令接口

:用户说一句,系统做一句:

在这里插入图片描述
敲一个指令,系统做一个指令。

脱机命令接口

又称为批处理命令接口
:用户说一堆,系统做一堆:
对于*.bat的一系列命令,系统会依次运行。

在这里插入图片描述

程序接口

在这里插入图片描述
用户接口总图:

在这里插入图片描述
GUI:
我的理解就是图形形象化吧。
在这里插入图片描述
最后这3者的分析:
在这里插入图片描述

3、最接近硬件的层次

操作系统的概念和定义与功能和目标:

操作系统的特征

操作系统有四个特征:并发、共享、虚拟、异步。其中并发和共享是两个最基本的特征,二者存在互为条件。
并发
并发是指宏观上同时发生,微观上是交替发生的,而并行是微观上同时发生。

虽然现在已经有4核处理机,但是往往我们的电脑中都有超过4个程序,包括还有系统额外的进程,所以并发性还是必不可少的。

共享:

互斥共享方式指的是系统中的某些资源,虽然可以提供给多个进程使用,但是一个时间段内只允许一个进程访问该资源,比如摄像头。
同时共享方式指的是允许一个时间段由多个进程“同时”对它们访问。这里的“同时”为什么要加引号呢,因为这里的同时有可能在微观上是交替访问的(即分时共享),比如访问硬盘资源,读取文件。也有可能在微观上是同时的(并行),比如扬声器可以一边放游戏音乐,一边放qq音乐。
在

并发和共享的关系

并发和共享互为存在条件
在这里插图片描述

虚拟

虚拟的知识在后面会着重讲解,这里有个印象就行。
下面用两个例子来简单说明一下:

在这里插入图片描述
没有并发性,就谈不上虚拟性了。
在这里插入图片描述

异步

只有拥有了并发性,才有可能导致异步性
在这里插入图片描述
总结回顾:
在这里插入图片描述

操作系统的发展和分类

下图是发展的流程:

在这里插入图片描述
下面按顺序出现,都是为了解决上一阶段的主要缺点!

手工操作阶段

由于计算机只能识别2进制,所以用纸带,打孔为1,不打孔为0。缺点很明显,输入输出慢,并且必须一个人输入输出一整个过程结束后,才轮到下一个人,也就是用户独占全机。
在这里插入图片描述

单道批处理系统

其实就是多个程序员将纸带的内容导入道磁带里,然后由cpu统一处理,再输出道磁带中,这里用了磁带,比纸带快很多,优化了上面的人工操作。这里其实已经是操作系统的雏形了。
但是缺点也很明显:内存中只能有一道程序运行,只有该程序运行结束后才能调用下一道程序。CPU的I/O有大量时间是空闲的,资源利用率还是很低。
在这里插入图片描述

多道批处理系统

优化了上面的单道批处理,一次性往内存中输入多道程序,由操作系统并发的执行。这里操作系统正式诞生。
但是缺点仍然有:没有提供人机交互的能力,用户把自己的程序输入到系统后,需要一直等待到运行结束或者运行异常了,把结果输出到磁带上,运行途中用户并不能和自己的程序交互。并且因为中途不能和程序交互,所以还有用户响应时间长的问题。
在这里插入图片描述
这里我们来分析一下为什么多道批处理系统的资源利用率大幅提升。
假设我们当前有三个作业:
在这里插入图片描述
若采用单道批处理系统:
在这里插入图片描述
若采用多道批处理系统:
在这里插入图片描述
在多道批处理系统中,我们发现输入、计算、输出设备都在尽可能的忙碌了起来。
我们可以看到单道批处理系统要9s,而多道批处理系统只需要5s,效率大大的提高了。

分时操作系统

分时系统主要是处理上面多道批处理系统不具有的人机交互问题。
计算机以时间片为单位轮流为各个用户/作业服务,各个用户可以通过终端和计算机进行交互。
主要优点:可以实现人机交互,并且允许多个用户同时使用一台计算机,并且用户对计算机的操作相互独立,感受不到别人的存在。
但是缺点就是,以时间片为单位的话,操作系统对各个用户/作业都是完全公平的,也就不能处理一些紧急任务了,区分不了任务的紧急性。
在这里插入图片描述

实时操作系统

能够响应一些紧急任务,某些紧急任务不需时间片排队。
实时操作系统又分为硬实时系统和软实时系统。
硬实时系统:必须在绝对严格的规定时间内完成处理,比如导弹控制系统、自动驾驶系统。
软实时系统:能接受偶尔违反时间规定,比如12306火车订票系统。

其他

还有网络操作系统、分布式操作系统和个人计算机操作系统:如Windows XP、MacOS。这些都不做详细介绍了。

知识回归于重要考点

在这里插入图片描述

操作系统的运行机制、体系结构

知识总览
在这里插入图片描述
预备知识:指令
在这里插入图片描述
指令又分成两种:特权指令和非特权指令。
我们用户一般只能使用非特权指令,而CPU在运行指令前也会先检查有没有运行当前指令的权限。
在这里插入图片描述
那么CPU又是怎么判断当前指令是否可以执行呢?
为此,我们规定了CPU的两种状态:用户态(目态)和核心态(管态)
如果CPU处于用户态,那么CPU只能执行非特权指令。
如果CPU处于核心态,那么特权指令和非特权指令CPU都能执行。
而CPU的这两种状态用程序状态字寄存器来标识。
在这里插入图片描述
我们把应用程序也分成了两种:内核程序和应用程序。
内核程序运行在核心态,应用程序运行在用户态。
在这里插入图片描述
两种指令、两种处理机状态、两种程序:
在这里插入图片描述
接下来提出一个问题:操作系统中的哪些功能应该由内核程序实现呢?
我们可以把操作系统细分:
在这里插入图片描述
内核是计算机上配置的底层软件,是操作系统最基本、最核心的部分。
实现操作系统内核功能的那些程序就是内核程序。
不同的操作系统对内核功能的划分可能并不一样。
在这里插入图片描述
操作系统的体系结构分为大内核和微内核:
在这里插入图片描述

在这里插入图片描述
知识回顾:
在这里插入图片描述

中断

本质:发生中断就意味着需要操作系统介入,开展管理工作。 知识总览:

在这里插入图片描述
最开始的电脑串行运行程序,资源利用率低。
后来人们发明了操作系统,引入了中断机制,实现了多道程序并发执行。
假设当前有3个程序需要运行。进程1进入CPU,在用户态下运行,运行了一段时间后,CPU收到计时部件发出的中断信号,切换为核心态,对中断进行处理。然后操作系统内核负责对中断信号进行处理。这时操作系统收到进程1的时间片已经用完,然后就换进程2运行。然后进程2开始在用户态下开始运行。在进程2运行的时候有可能会发出系统调用(内中断信号),请求输出。CPU切换为核心态,对中断进行处理。然后又切换为核心态,操作系统内核负责对中断信号尽心处理,然后进程2暂停运行等待I/O完成,换进程3运行。然后再切换为用户态,进程3运行并且输出设备和进程3并行的工作。当输出设备结束以后,设备向CPU发出中断信号,切换为核心态,之后继续让进程2运行,切换为用户态。
中断的概念和作用
在这里插入图片描述
遗留问题:用户态、核心态之间的切换是怎么实现的?
“用户态->核心态”是通过中断实现的。并且中断是唯一途径。
“核心态->用户态”的切换是通过执行一个特权指令,将程序状态字(PSW)的标志位设置为“用户态”。
中断可以分为内中断和外中断两种大类。
两种中断的区别是信号的来源:内中断的信号来源是CPU内部,与当前执行指令有关。外中断的信号来源是CPU外部,与当前执行的指令无关。
在这里插入图片描述
中断还有以下这种分类方式:
在这里插入图片描述
外中断的处理过程
在这里插入图片描述
知识回顾和重要考点:
在这里插入图片描述

系统调用

知识总览:

在这里插入图片描述
什么是系统调用,有何作用?
系统调用会使用一个trap(陷入)指令,使处理器从用户态到核心态。
系统调用其实就是对进程的一种协调管理。当多个进程访问一个资源时,进程本身无法做到协调,所以这时我们把这些进程都丢给操作系统,由操作系统为我们统一管理,这样可以保证系统的稳定新和安全性,防止用户进行非法操作。所以操作系统需要在核心态下运行。
在这里插入图片描述
在这里插入图片描述
操作系统的分类:
在这里插入图片描述
由于系统调用的很多行为涉及到对硬件等底层的管理,所以需要很高的权限,因此系统调用的相关处理需要在核心态下进行。
系统调用和库函数的区别
系统调用被划分为核心态下。
在这里插入图片描述

系统调用和库函数的区别:
我们程序员使用的都是高级语言比如c语言,java,其中有的库函数其实底层实现了系统调用知识我们看不到。
在这里插入图片描述
系统调用背后的过程:
首先我们把高级语言编译成汇编语言(用户态下),然后执行系统调用的指令(核心态下)。下图中的write("abc")被划分成了前期处理相关指令,过程、后续处理相关指令,就是库函数的底层封装了系统调用。
下图中还有3个注意。解释以下3:我们直到核心态下可以执行特权指令和非特权指令,而用户态下只能执行非特权指令,但是核心态下有且只有一个不能执行的非特权指令就是陷入指令。

在这里插入图片描述
知识回顾:
系统调用发生在用户态,而对系统调用的处理发生在核心态。
在这里插入图片描述

进程的定义、组成、组织方式、特征

知识总览

进程的定义
首先我们先来了解一下程序是什么:
最开始的单道程序:
在这里插入图片描述
引入多道程序之后:
上面的单道程序中,因为程序只有一个,所以只要把代码和数据放在指定的地址就行了。但是多道程序内存中同时放入多道程序,各个程序的代码、运算数据存放的位置不同。操作系统要怎么才能找到各程序的存放位置呢?
由于每个程序的指令不一样,每个指令分得的cpu,I/O都不一样,所以这里为了方便操作系统管理,完成各程序并发执行,引入了进程、进程实体的概念。
系统为每个运行的程序配置了一个数据结构,称为进程控制器(PCB),用来描述进程的各种信息(如进程代码存放位置)。
PCB、程序段、数据段三部分构成了进程实体(进程映像)。
在这里插入图片描述
进程的定义:
程序段、数据段、PCB三部分组成了进程实体(进程映像)。一般情况下,我们把进程实体就简称为进程,例如,所谓创建进程,实质上是创建进程实体中的PCB;而撤销进程,实质上是撤销进程实体中的PCB。
注意:PCB是进程存在的唯一标志!
从不同的角度,进程可以由不同的定义,不过这些定义都强调了进程的动态性:
在这里插入图片描述
进程的组成
进程(进程实体)由PCB、数据段、程序段三部分组成。
在这里插入图片描述
PCB的内容信息:
在这里插入图片描述

在考试中,我们可能会碰到当前指令是否在PCB中,我们其实没必要去 背,只要是对进程的管理,都是在PCB中,而进程本身运行所需的数据都在程序段和数据段中。
在这里插入图片描述
进程的组织:
在一个系统中,通常有数十、数百甚至数千个PCB,为了能对他们加以有效的管理,应该用适当的方式把这些PCB组织起来。
注:进程的组成讨论的是一个进程内部由哪些部分构成的问题,而进程的组织讨论的是多个进程之间的组织方式问题。
进程的组织方式分为链接方式和索引方式。
在这里插入图片描述
链接方式:
在这里插入图片描述
索引方式:
在这里插入图片描述
进程的特征
进程和程序是两个截然不同的概念,相比于程序,进程拥有以下特征:
动态性、并发性、独立性、异步性、结构性。
在这里插入图片描述
知识回顾:
在这里插入图片描述

进程的状态和转换

知识总览:

在这里插入图片描述
进程的状态—三种基本状态
进程是程序的一次执行。在这个执行的过程中,有时进程正在被CPU处理,有时又需要等待CPU服务,可见,进程的状态时会有变化的,为了方便对各个进程的管理,操作系统需要将进程合理地划分为几种状态:
进程地三种基本状态:运行态、就绪态、阻塞态:

在这里插入图片描述
进程地另外两种状态:创建态和终止态。
在这里插入图片描述
进程状态的转换
在这里插入图片描述
知识回顾:
在这里插入图片描述

进程控制

知识总览:

在这里插入图片描述
什么是进程控制
进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销以有进程、实现进程状态转移等功能。
简化理解:反正进程控制就是要实现进程状态转换
在这里插入图片描述
如何实现进程控制
首先回顾一下之前学的进程的组织中的链接方式:
在这里插入图片描述
然后我们细化一下:
在这里插入图片描述
我们发现在状态转移中,需要修改的信息还是很多的,比如说一个PCB转移到了另一个队列,但是这个PCB的状态还没来得及更新,来了一个外中断信号,等处理完外中断信号之后,这个PCB的状态更新已经被忘记了,这样就会出很大的问题,极有可能会发生系统错误,所以我们用原语来实现进程控制。
原语的特点是执行期间不允许中断,只能一气呵成。
这种不可被中断的操作即原子操作。
原语采用“关中断指令”和“开中断指令”实现。
原语运行在核心态,可以看到关中断和开中断的权限非常大。

在这里插入图片描述
进程控制相关的原语
无论哪个原语,要做的无非三类事情:
在这里插入图片描述
创建原语
在这里插入图片描述
撤销原语
在这里插入图片描述
阻塞和唤醒原语
在这里插入图片描述
切换原语
在这里插入图片描述
知识回顾:
在这里插入图片描述

进程通信

知识总览

在这里插入图片描述
什么是进程通信
顾名思义,进程通信就是指进程之间的信息交换。
在这里插入图片描述
比如我们在软件上看到一张好看的图片,想分享给我们的小伙伴,就可以点分享按钮,那么从图片进程到分享进程,这之间就得有进程通信才行。
所以操作系统提供了一些方法:共享存储、消息存储、管道存储。
共享存储
共享存储有两种方式:基于数据结构的共享、基于存储区的共享
在这里插入图片描述
管道通信
在这里插入图片描述
消息传递
根据操作系统提供的发送消息原语和接受消息原语进行数据交换。
消息传递有直接通信消息和间接通信消息两种方式。
在这里插入图片描述

知识回顾
在这里插入图片描述

线程概念多线程模型

知识总览

在这里插入图片描述
什么是线程,为什么要引入线程?
可以把进程理解为”轻量级进程“。
线程是一个基本的CPU执行单元,也是程序执行流的最小单位。
在这里插入图片描述
在这里插入图片描述
在引入了线程后,进程只作为除CPU之外的系统资源的分配单位,比如打印机、内存地址空间等都是分配给进程。

在这里插入图片描述
引入线程机制后,有什么变化?
在这里插入图片描述
线程的属性
在这里插入图片描述
线程的实现方式
线程有分为用户级线程和内核级线程。
用户级线程:
在这里插入图片描述
内核级线程:
又称内核支持的线程。
在这里插入图片描述

线程的实现方式
在这里插入图片描述
多线程模型
多对一:
在这里插入图片描述
一对一:
在这里插入图片描述
多对多:
在这里插入图片描述
知识回顾:
在这里插入图片描述

12、处理机调度的概念和层次

知识总览

在这里插入图片描述
调度的基本概念
在这里插入图片描述
调度的三个层次——高级调度

在这里插入图片描述
中级调度
这里为什么PCB不会一起调到外存呢?因为内存要知道这些进程都被调到外存的哪些地方了,而要想知道,就得把进程在外存的地址记录在它的PCB中。
在这里插入图片描述
补充知识:进程的挂起态与七状态模型
在这里插入图片描述
低级调度
在这里插入图片描述
三层调度的联系和对比
在这里插入图片描述
知识回顾

在这里插入图片描述

13、进程调度的时机和切换与过程调度方式

知识总览

在这里插入图片描述
进程调度的时机

在这里插入图片描述
对于进程在操作系统内核程序临界区中不能进行调度和切换。
在这里插入图片描述
但是对于普通的临界区,是可以进行进程调度和切换的。
在这里插入图片描述
剥夺调用方式和非剥夺调用方式
有的系统中,只允许进程主动放弃处理机,但是有的系统,进程可以主动放弃处理机,当有更紧急的任务需要处理时,也会强行剥夺处理机(被动放弃)。
那么当前的进程是否可以被强行的剥夺处理机资源我们引出了进程调度的方式:剥夺调用方式(非抢占式)和非剥夺调用方式(抢占式)。

在这里插入图片描述
进程的切换与过程
在这里插入图片描述
知识回顾
在这里插入图片描述

14、调度算法的评价指标

知识总览

在这里插入图片描述
CPU利用率
在这里插入图片描述
系统吞吐量
就是单位时间内完成作业的数量。
在这里插入图片描述

周转时间
就是指作业被提交给系统开始,到作业完成为止的这段时间间隔
在这里插入图片描述
带权周转时间
在这里插入图片描述
等待时间
在这里插入图片描述
响应时间
在这里插入图片描述
知识回顾
在这里插入图片描述

调度算法

先来先服务(FCFS)
短作业优先(SJF)
高响应比优先(HRRN)
时间片轮转算法(RR)
优先级调度算法
多级反馈队列调度算法

先来先服务(FCFS)

在这里插入图片描述

在这里插入图片描述

短作业优先(SJF)h2>

在这里插入图片描述

短作业优先分为可抢占式的和不可抢占式的
不可抢占式的:
在这里插入图片描述
可抢占式的:
在这里插入图片描述
在这里插入图片描述
注意:
在这里插入图片描述
对FCFS和SJF算法的思考
在这里插入图片描述

高响应比优先(HRRN)

在这里插入图片描述

在这里插入图片描述

时间片轮转算法(RR)

在这里插入图片描述
时间片为2的情况:
在这里插入图片描述
在这里插入图片描述
时间片为5的情况
在这里插入图片描述
问题:
时间片太大或太小都不好。
在这里插入图片描述
在这里插入图片描述

优先级调度算法

在这里插入图片描述

非抢占式:
在这里插入图片描述
抢占式:
在这里插入图片描述
补充
在这里插入图片描述

多级反馈队列调度算法

思考
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
总结:
在这里插入图片描述
在这里插入图片描述

进程同步、进程互斥

知识总览

在这里插入图片描述
什么是进程同步?
在这里插入图片描述
同步亦称直接制约关系,它是指为完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调他们的工作次序而产生的制约关系。进程间的直接制约关系就是源于他们之间的相互合作。
在这里插入图片描述
什么是进程互斥?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
知识回顾
在这里插入图片描述

进程互斥的软件实现方法

知识总览

在这里插入图片描述
单标识法
可以实现互斥,但是违背了空闲让进的原则。
在这里插入图片描述

问题:

在这里插入图片描述
双标志先检查法
解决了上面单标志法的“空闲让进”的问题,但是又有了“忙则等待”的问题。
原因在于检查的上锁不是一起原子性的,在检查后可能导致进程切换。
在这里插入图片描述
双标志后检查法
虽然解决了“忙则等待”的问题,但是又违背了“空闲让进”和“有限等待”原则,会因各进程都长期无法访问临界资源而产生“饥饿”现象。
在这里插入图片描述
Peterson算法
用软件方法解决了进程互斥问题,遵循了空闲让进、忙则等待、有限等待三个原则,但是依然未遵循让全等待的原则。
相较于上面三种软件解决方案来说,是最好的,但依然不够好。
在这里插入图片描述
在这里插入图片描述
知识回顾
在这里插入图片描述

进程互斥的硬件实现方法

知识总览
在这里插入图片描述
中断屏蔽
不适用于多处理机,处理机A对进程实现了关中断,但是处理机B依然可以实现进程切换,所以不适用于多处理机。
在这里插入图片描述
TestAndSet指令
不满足“让权等待”,导致忙等。
在这里插入图片描述
Swap指令
有的地方叫Exchange指令,或简称XCHG指令。
不满足“让权等待”,导致忙等。
在这里插入图片描述
知识回顾
在这里插入图片描述

信号量机制

知识总览
在这里插入图片描述
信号量机制
在这里插入图片描述
整型信号量
也不满足“让权等待”,会发生忙等。
在这里插入图片描述
记录型信号量
在这里插入图片描述
下面对例子讲解:
一开始value的值为2,p0进程进来后,value=1,p1进程进来后,value=0,p2进程进来后,value=-1,这时value<0,所以把p2放入等待队列中(p2),然后p3进来,value=-2,这时value<0,所以把p3放入等待队列中(p2->p3),然后p0进程结束,value=-1,这时value<=0,所以从等待队列(p2->p3)中唤醒第一个,也就是p2,然后把打印机分配给p2,然后p1结束,value=0,这时value<=0,所以唤醒p3,然后把打印机分配给p3,然后p2接受,value=1,最后p3结束,value=2。
在这里插入图片描述
在这里插入图片描述
知识回顾
在这里插入图片描述

用信号量机制来实现进程互斥、同步、前驱关系

知识总览

在这里插入图片描述

信号量机制实现进程互斥
在这里插入图片描述
信号量机制实现进程同步
在这里插入图片描述
在这里插入图片描述
信号量机制实现前驱关系
在这里插入图片描述
知识回顾与重要考点
在这里插入图片描述

生产者消费者问题

问题描述
系统中有一组生产者进程和消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用(注:这里的产品理解为一种数据)
生产者、消费者共享一个初始为空、大小为n的缓冲区。
(1)只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待。
(2)只有缓冲区不空时,消费者才能从中取出产品,否则必须等待。
(3)缓冲区时临界资源,各进程必须互斥的访问。(如果不互斥访问,那么多个生产者可能看中了缓冲区的同一块区域,就会出问题)
首先我们分析问题:信号量可以实现互斥、同步、对一类系统资源的申请和释放(设置一个信号量,初始值即为资源的数量,这个本质上其实也是同步问题,因为如果当前没有空闲资源,那么申请资源的进程需要等待别的进程释放资源后才能继续往下执行,也是一前一后的关系。
那么在当前题中,:
(1)是个同步问题,因为当缓冲区满了,生产者就要等消费者消费后才能再继续生产,一前一后。
(2)是个同步问题,当缓冲区为空的时候,只有生产者生产了产品,消费者才能继续消费。
(3)是个互斥问题,各个消费者之间要互斥访问缓冲区,各个生产者之间也要互斥访问缓冲区。
也就是说,生产者每次要消耗(P)一个空闲的缓冲区,然后生产(V)一个产品。消费者每次要消耗(P)一个产品,然后释放(V)一个空闲缓冲区。
往缓冲区放入/取走产品需要互斥。
所以我们需要设置3个信号量:

semaphore mutex = 1;
semaphore empty = n;
semaphore full = 0;

生产者:

productor {
	while(1) {
		生产一个产品
		P(empty); 
		P(mutex);
		把产品放入缓冲区;
		V(full);
		V(mutex);
	}
}

消费者:

consumer{
	while(1) {
		生产一个产品
		P(full);
		P(mutex);
		把产品放入缓冲区;
		V(empty);
		V(mutex);
	}
}

这里要注意, P(meutx)在P(empty)和P(full)的后面,是因为实现互斥的P操作一定要在实现同步的P操作之后。具体原因看后面的图片详解。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
知识回顾
在这里插入图片描述

多生产者-多消费者

问题描述

在这里插入图片描述
问题分析
在这里插入图片描述
代码实现
在这里插入图片描述
我们发现一个问题,可不可以不要这个互斥信号量呢?
看下面的分析:
在这里插入图片描述
我们发现即使不设置互斥信号量,也不会出现多个进程同时访问盘子的现象。
原因:
在这里插入图片描述
这里是因为缓冲区为1,如果为2的话,那么当爸爸P(plate),然后妈妈P(plate),可能就会访问到同一块缓冲区,造成数据覆盖,这时就必须要设置一个互斥信号量mutex来保证互斥访问缓冲区。
在这里插入图片描述
知识回顾
在这里插入图片描述
分析解题思路
在这里插入图片描述

吸烟者问题

问题描述
在这里插入图片描述
问题分析
在这里插入图片描述
在这里插入图片描述
这里注意因为finish初始值为0,所以如果P(finish)在开头的话,就永远无法运行下去。
在这里插入图片描述
知识回顾
在这里插入图片描述

读者、写者问题

问题描述
在这里插入图片描述
问题分析
在这里插入图片描述
如何实现
实现一:默认读进程是优先的,有可能会产生饿死。
在这里插入图片描述
实现二:
在这里插入图片描述
知识回顾
在这里插入图片描述

哲学家进餐问题

问题描述
在这里插入图片描述
问题分析
第一种最简单的思考就是:
在这里插入图片描述
但是这种情况在每个哲学家拿完左边的时候,并发跳到另一个哲学家,依次这样就会发生每个哲学家都只有左边的筷子,就会发生死锁的情况。
所以我们接下来引发了下面的3种解决方案:
前两种:
在这里插入图片描述
第三种:
在这里插入图片描述
知识回顾
在这里插入图片描述

管程

知识总览
在这里插入图片描述
为什么要引入管程
管程的引入主要是信号量机制编写程序困难并且容易出错。
管程是由编译器实现进程互斥,用条件变量实现同步机制。
在这里插入图片描述
管程的定义和基本特征
在这里插入图片描述
用管程解决生产者消费者问题
这里的条件变量实际上是一个队列,比如empty就是一个当缓冲区为空的时候,消费者的队列。full就是当缓冲区满了的时候,生产者的队列。
在这里插入图片描述
总结一下:
在这里插入图片描述
"JAVA"中类似于管程的机制
其实就是synchronized的运用。

在这里插入图片描述

知识回顾
在这里插入图片描述

死锁的概念

知识总览
在这里插入图片描述
什么是死锁
在之前的哲学家问题中,最开始最简单的思考就会引发死锁,因为当每个人都拿起左手的筷子的时候,然后并发跳到另一个进程,再只拿起左边的筷子,就会发生每个人都只拿着左手的筷子,就会发生死锁。
死锁其实就是,我手里有一些资源,但是我又想要别人手里的资源,而别人手里又正好缺我手里的资源,就会发生死锁。
在这里插入图片描述
在这里插入图片描述
死锁、饥饿、死循环的区别
在这里插入图片描述
死锁产生的必要条件
互斥条件、不剥夺条件、请求和保持条件、循环等待条件。
在这里插入图片描述
什么时候会发生死锁
对不可剥夺资源的不合理分配,可能会导致死锁。
在这里插入图片描述
死锁的处理策略
1、预防死锁
2、避免死锁
3、死锁的检测和解除
这三个会在后面3章一次详解。
在这里插入图片描述
知识回顾
在这里插入图片描述

死锁的处理策略——预防死锁

知识总览

在这里插入图片描述

破坏互斥条件
在这里插入图片描述
破坏不剥夺条件
在这里插入图片描述
破坏请求和保持条件
在这里插入图片描述
破坏循环等待条件
在这里插入图片描述
知识回顾
在这里插入图片描述

死锁的处理策略——避免死锁

知识总览
在这里插入图片描述
什么是安全序列
现在有一个问题:我是一个成功的银行家,手里有100亿,现在又三个企业B,A,T想找我借钱,B要找我借70亿,A要找我借40亿,T要找我借50亿。
如果我不把他们需要的所有钱都借给他们的话,他们就不会还我的钱。
刚开始,BAT三个公司分别找我借了20,10,30亿。
这时的情况是这样的:
在这里插入图片描述
这时我手里还有40亿,如果B还想借30亿,能借吗?如果我借了B30亿,手机还剩10亿,这时的情况就变成了在这里插入图片描述
那么我现在手里的钱谁都满足不了,所以这钱不能借。
那如果A找我借20亿,我敢借吗?
尝试一下,我借了A20亿以后,那么现在就变成了:
在这里插入图片描述
那么我现在手机还剩20亿,我这20亿可以先借给T,T得到了所需要的所有钱,就会还我50亿,我手里就还剩70亿,我再拿着70亿去借B和A,这样就解决了所有的问题。或者我拿这20亿中的10亿先借给A,A得到了所需要的所有钱就会还我40亿,我手里就还剩50亿,然后我再拿着50亿依次去借B和T,也可以解决所有的问题。
根据上面的例子我们可以发现,有的资源请求是不合理的,有的资源请求我们是可以答应的,上面给A借20亿是因为存在T->B->A这样的安全序列
所谓安全序列:就是指如果系统按照这种序列分配资源,则每个进程都能顺利完成。只要能找出一个安全序列,系统就是安全状态。当然,安全序列可能有很多个。
如果分配了资源之后,系统中找不到任何一个安全序列,系统就进入了不安全状态。这就意味着之后可能所有进程都无法顺利地执行下去。当然,如果有进程提前归还了一些资源,那系统也有可能重新回到安全状态,不过我们分配资源之前总是要考虑到最坏的情况。
如果系统处于安全状态,就一定不会发生死锁。如果系统进入不安全状态,就可能发生死锁(处于不安全状态未必就是发生了死锁,但发生死锁时一定是在不安全状态)
因此可以在资源分配之前预先判断这次分配是否会导致系统进入不安全状态,以此来决定是否答应资源分配请求,这也是“银行家算法”的核心思想。
银行家算法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
正式实现银行家算法:
在这里插入图片描述
知识回顾
在这里插入图片描述
注意: 系统处于不安全状态未必死锁,但死锁时一定处理不安全状态。系统处于安全状态一定不会死锁。

死锁的处理策略——检测和解除

知识总览
在这里插入图片描述
死锁的检测
在这里插入图片描述
其实就是一直简化边,如果能简化所有的边,就说明没有发生死锁,如果不能的话,就说明会发生死锁。
在这里插入图片描述
在这里插入图片描述
死锁解除
在这里插入图片描述
知识回顾
在这里插入图片描述

内存的基础知识

知识总览
在这里插入图片描述
什么是内存?有何作用?
在这里插入图片描述
补充知识:几个常用的数量单位
在这里插入图片描述
进程的运行原理–指令
在这里插入图片描述
逻辑地址vs相对地址
在这里插入图片描述
从写程序到程序运行
在这里插入图片描述从程序到程序运行
下面的装入模块其实就是.exe文件。
在这里插入图片描述
装入模块装入内存
在装入模块中,里面所有的地址都是逻辑地址,也就是从0开始的,但是当装入内存以后,有可能在内存中是从100开始的,如果我们不修改指令的地址,装入就会出现错误。
所以我们可以用三种方式来解决这种问题:绝对装入、静态重定位、动态重定位。
绝对装入
如果一开始我们就知道这段程序会放到内存的哪个位置,那一开始我们就可以把地址写成绝对地址(物理地址)。
但是这种方法只适用于单道程序环境,在任意时刻只会有一个程序运行,我们就能知道程序会从哪个地方开始存放。
这里注意,这是编译的时候!!!!!!而且这时候是单道批,还没有操作系统。
在这里插入图片描述

静态重定位
根据内存的当前情况,将装入模块装到内存的适当位置,在装入的时候对地址进行“重定位”,将逻辑地址变换为物理地址(地址变换是在装入时一次完成的)。
注意:这里是装入的时候改变地址,用于早期的多道批处理操作系统。
在这里插入图片描述
动态重定位
装入模块装入内存以后,并不会改变装入模块的逻辑地址,而是用一个重定位寄存器(存放装入模块在内存中的起始位置),在真正要运行的时候,才会用加法的方法根据逻辑地址得到物理地址。
动态重定位法允许程序在内存中移动。
在这里插入图片描述
在这里插入图片描述

链接的三种方式

链接也有三种方式:静态链接

在这里插入图片描述

知识回顾
在这里插入图片描述

内存管理的概念

在这里插入图片描述
1、内存空间的分配与回收
我们可以提出3个问题。
1、操作系统要怎么记录哪些内存区域已经被分配出去了,哪些又还空闲?
2、如果内存中很多地方都可以放,那应该放在哪里?
3、当进程结束之后,如果将进程占用的内存空间回收?
所以首先,操作系统要负责内存空间的分配与回收。
2、内存空间的扩展
操作系统需要提供某种技术从逻辑上对内存空间进行扩充

在这里插入图片描述
3、地址转换
操作系统需要提供地址转换功能,负责程序的逻辑地址和物理上地址的转换。
在这里插入图片描述
这里地址重定位的方法就是上一小节提到的三种装入方式:绝对装入、可重定位装入、动态运行时装入。
在这里插入图片描述
4、内存保护
操作系统需要提供内存保护功能。保证各进程在各自存储空间运行,互不干扰。
内存保护有两种方法:
方法一:
在这里插入图片描述
方法二:
在这里插入图片描述
知识回顾
在这里插入图片描述

覆盖与交接

**知识总览**

覆盖技术
在这里插入图片描述
在这里插入图片描述
交换技术
注意:PCB会常驻内存,不会被换出外存。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
知识回顾
在这里插入图片描述

连续分配管理方式

知识总览
在这里插入图片描述
单一连续分配方式
在这里插入图片描述
固定分区分配
在这里插入图片描述
在这里插入图片描述
动态分区分配
动态分区分配是在进程装入内存的时候,根据进程的大小动态的建立分区。
那么我们可以提出三个问题:
1、由于分配的内存的大小都是可变的,所以系统要用什么样的数据结构记录内存的使用情况?
2、当什么多空闲分区都能满足需求时,应该选择哪个分区进行分配?
3、当一段内存释放后,它是否应该跟它相邻的内存合并,也就是 如何进行分区的分配与回收操作?

在这里插入图片描述
先来看第一个问题:系统要用什么样的数据结构记录内存的使用情况?
一般采用两种常用的数据结构:空闲分区表和空闲分区链
在这里插入图片描述
问题二:当什么多空闲分区都能满足需求时,应该选择哪个分区进行分配?
当我们把一个新作业装入内存时,必按照一定的动态分区分配算法,这个算法我们会在下面的小节一次介绍。
在这里插入图片描述

问题三:当一段内存释放后,它是否应该跟它相邻的内存合并,也就是 如何进行分区的分配与回收操作?
1、如何分配:
第一种情况:只要把分区的起使地址和分区大小改一下就行了。
在这里插入图片描述

第二种情况:
当分区的大小被全部分配完时,把分区号给删掉
在这里插入图片描述
上面是空闲分区表,空闲分区链也是一样的原理。
2、如何回收
分4中情况:
第一种情况:
在这里插入图片描述
第二种情况
在这里插入图片描述
第三种情况
在这里插入图片描述
第四种情况
在这里插入图片描述

动态重定位这个装入方式更好。
在这里插入图片描述
知识总览
在这里插入图片描述

动态分区分配算法

知识总览
在这里插入图片描述
在这里插入图片描述
最佳适应算法
在这里插入图片描述
最坏适应算法
又称最大适应算法
在这里插入图片描述
邻近适应算法
在这里插入图片描述
知识回顾
在这里插入图片描述

基本分页存储管理的基本概念

思考
上面的四种连续分配方式都有各自的缺点。
所以产生了“非连续分配方式”,或者成为“离散分配方式”
在这里插入图片描述
知识总览
在这里插入图片描述
把固定分区分配改造成非连续分配版本
在这里插入图片描述
分页存储管理的基本概念
在这里插入图片描述
思考:如何实现地址的转换
先来看看之前的连续分配方式是怎么实现地址转换的:

在这里插入图片描述
在这里插入图片描述
接下俩看看离散分配方式的地址转换方式:
为了方便计算页号、页内偏移量,页面大小一般设为2的整数幂。
结论:如果每个页面大小为2的k次方B,用二进制表示逻辑地址,则末尾K位即为页内偏移量,其余部分就是页号。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

逻辑地址结构
在这里插入图片描述
页表
在这里插入图片描述
对下面这张图做一下讲解,当时看的时候懵了好一会,主要还是名词意思理解错了。这里的意思是,当前可算出一个内存块号的大小得由3个字节才够表示,并且各表项是顺序存放的,假如当前起使位置为0,也就是说1号页的块号在内存地址为0,1,2,而2号页就存放在3,4,5。所以第M号就在X + 3 * M,X + 3 * M + 1, X + 3 * M + 2。
所以说页号可以是隐含的,因为只要只要页表的起始位置和页表项的长度,就能直接知道各个页号对应的页表项存放的位置。

在这里插入图片描述
在这里插入图片描述

基本地址变化机构

知识总览
在这里插入图片描述
基本地址变换机构
在这里插入图片描述

图片讲解:
在这里插入图片描述

文字讲解:
在这里插入图片描述
验证:
在这里插入图片描述
E = 2 * 1024 + 1023 = 3071
b的2进制 = 10
W的2进制 = 1111111111
拼接起来就是101111111111 = 3071。验证成功。
实题操练
在这里插入图片描述
对页表项大小的进一步探讨
在这里插入图片描述
知识回顾
在这里插入图片描述

具有快表的地址变换机构

知识总览
在这里插入图片描述
在这里插入图片描述
什么是快表
在这里插入图片描述
在这里插入图片描述
引入快表之后,地址的变换过程
在这里插入图片描述
知识回顾
在这里插入图片描述

两级页表

知识总览

在这里插入图片描述

单级页表存在的问题
在这里插入图片描述
在这里插入图片描述
如何解决单级页表存在的问题
在这里插入图片描述

两级页表的原理、地址结构
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
问题二
在这里插入图片描述
需要注意的几个细节
在这里插入图片描述
知识回顾
在这里插入图片描述

虚拟内存的基本概念

知识总览

在这里插入图片描述
在这里插入图片描述
传统存储管理方式的特征、缺点
在这里插入图片描述
局部性原理
时间局部性、空间局部性
在这里插入图片描述
虚拟内存的定义和特征
在这里插入图片描述
虚拟内存的3个特征在这里插入图片描述

知识回顾
在这里插入图片描述

请求分页管理方式

知识总览
在这里插入图片描述
页表机制
在这里插入图片描述
缺页中断机构
属于内终端
在这里插入图片描述
在这里插入图片描述
地址变换机构
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
知识回顾
在这里插入图片描述

页面置换算法

知识总览
在这里插入图片描述

最佳置换算法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
先进先出置换算法在这里插入图片描述

在这里插入图片描述
最近最久未使用算法(LRU)
在这里插入图片描述
时钟置换算法(CLOCK)
简答的时钟置换算法:
在这里插入图片描述
改进后的时钟置换算法
在这里插入图片描述

知识回顾
在这里插入图片描述

页面分配策略

知识总览
在这里插入图片描述
页面分配、置换策略
在这里插入图片描述
在这里插入图片描述

何时调入页面
在这里插入图片描述
从何处调入页面
在这里插入图片描述
抖动(颠簸)现象

在这里插入图片描述

工作集
在这里插入图片描述
知识回顾
在这里插入图片描述

初始文件管理

前情回顾

在这里插入图片描述

操作系统应该向上提供哪些功能?
在这里插入图片描述
从上往下看,文件应如何存放在外存?
在这里插入图片描述
其它需要操作系统实现的文件的管理功能
在这里插入图片描述
知识回顾
在这里插入图片描述

文件的逻辑结构

知识总览
在这里插入图片描述
无结构文件
在这里插入图片描述
有结构文件
在这里插入图片描述
定长记录:在这里插入图片描述
可定长记录:
在这里插入图片描述
有结构文件的逻辑结构
在这里插入图片描述
顺序文件
在这里插入图片描述
在这里插入图片描述
索引文件
在这里插入图片描述
索引顺序文件

《空》

文件目录

在这里插入图片描述

知识总览
在这里插入图片描述
文件控制块(FCB)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
目录结构-单级目录结构
在这里插入图片描述
目录结构-两级目录结构
在这里插入图片描述
目录结构-多级目录结构(树型目录结构)
在这里插入图片描述
目录结构-无环图目录结构
在这里插入图片描述
索引节点(FCB的改进)
在这里插入图片描述
**在这里插入图片描述**
知识回顾
在这里插入图片描述

文件的物理结构(上)

知识总览
在这里插入图片描述
文件块、磁盘块
在这里插入图片描述
文件分配方式-连续分配
优点:

在这里插入图片描述
缺点:
在这里插入图片描述
在这里插入图片描述
总结:
在这里插入图片描述
文件分配方式-链接分配
分为隐式和显示链接。
隐式链接:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
显式链接:
在这里插入图片描述
在这里插入图片描述
链式分配(总结)
在这里插入图片描述

文件的物理结构(下)

索引分配
在这里插入图片描述
在这里插入图片描述
1、链接方案:
在这里插入图片描述
2、多级索引:
在这里插入图片描述
3、混合索引

文件共享

知识总览

在这里插入图片描述
基于索引节点的共享方式(硬链接)
在这里插入图片描述
基于符号链的共享方式(软链接)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
知识回顾
在这里插入图片描述

文件保护

知识总览
在这里插入图片描述
在这里插入图片描述
加密保护
在这里插入图片描述
在这里插入图片描述
访问控制
在这里插入图片描述
在这里插入图片描述
知识回顾
在这里插入图片描述

文件系统的层次结构

在这里插入图片描述
知识回顾
在这里插入图片描述

磁盘的结构

知识总览

在这里插入图片描述
磁盘、磁道、扇区
在这里插入图片描述
如何在磁盘中读、写数据
在这里插入图片描述
盘面、柱面
在这里插入图片描述
磁盘的分类

在这里插入图片描述

在这里插入图片描述

知识回顾
在这里插入图片描述

磁盘调度算法

知识总览
在这里插入图片描述
一次磁盘读、写操作需要的时间
在这里插入图片描述
先来先服务算法(FCFS)
在这里插入图片描述
最短寻找时间优先(SSTF)
在这里插入图片描述
扫描算法(SCAN)
在这里插入图片描述
LOOK调度算法
在这里插入图片描述
循环扫描算法(C-SCAN)

在这里插入图片描述
C-LOCK调度算法
在这里插入图片描述
知识回顾
在这里插入图片描述

I-O设备的概念和分类

知识总览
在这里插入图片描述
什么是I/O设备
在这里插入图片描述
**I/O设备的分类——按使用特性 **
分为3种类型:人机交互类外部设备、存储设备、网络通信设备
在这里插入图片描述
I/O设备的分类——按传输速率分类
分为3种设备:低速、中速、高速设备。
在这里插入图片描述
I/O设备的分类——按信息交换的单位分类
分为2种:块设备、字符设备
在这里插入图片描述
知识回顾
在这里插入图片描述

I-O控制器

知识总览
在这里插入图片描述
机械部件
在这里插入图片描述
I/O设备的电子部件(I/O控制器)
在这里插入图片描述
I/O控制器的组成
在这里插入图片描述
注意:
在这里插入图片描述
在这里插入图片描述
知识回顾
在这里插入图片描述

I-O控制方式

知识总览
在这里插入图片描述
程序直接控制方式
在这里插入图片描述
在这里插入图片描述
中断驱动方式
在这里插入图片描述
在这里插入图片描述
DMA方式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通道控制方式

知识回顾

I-O软件层次结构

知识总览
在这里插入图片描述
用户层软件
在这里插入图片描述
设备独立性软件

中断处理程序
在这里插入图片描述
知识点回顾
在这里插入图片描述

I-O核心子结构

知识总览
在这里插入图片描述
在这里插入图片描述
I/O调度
在这里插入图片描述
设备保护
在这里插入图片描述

假脱机技术(SPOOLing技术)

知识总览
在这里插入图片描述
什么是脱机技术
在这里插入图片描述
假脱机技术–输入进程和输出进程

在这里插入图片描述
共享打印机的实现
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
知识总览
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值