操作系统面试题

一、概述

1.解释一下什么是操作系统

操作系统是运行在计算机上最重要的一种软件,它管理计算机的资源和进程以及所有的硬件和软件。它为计算机硬件和软件提供了一种中间层,使应用软件和硬件进行分离,让我们无需关注硬件的实现,把关注点更多放在软件应用上。

2.操作系统的主要功能

进程、内存、设备、文件管理和提供用户接口。【回答】

一般来说,现代操作系统主要提供下面几种功能

进程管理: 进程管理的主要作用就是任务调度,在单核处理器下,操作系统会为每个进程分配一个任务,进程管理的工作十分简单;而在多核处理器下,操作系统除了要为进程分配任务外,还要解决处理器的调度、分配和回收等问题
内存管理:内存管理主要是操作系统负责管理内存的分配、回收,在进程需要时分配内存以及在进程完成时回收内存,协调内存资源,通过合理的页面置换算法进行页面的换入换出
设备管理:根据确定的设备分配原则对设备进行分配,使设备与主机能够并行工作,为用户提供良好的设备使用界面。
文件管理:有效地管理文件的存储空间,合理地组织和管理文件系统,为文件访问和文件保护提供更有效的方法及手段。
提供用户接口:操作系统提供了访问应用程序和硬件的接口,使用户能够通过应用程序发起系统调用从而操纵硬件,实现想要的功能。

3.软件(如用户进程等)访问硬件的几种方式

直接访问,中断驱动,DMA 直接内存访问,通道控制方式。【回答】

软件访问硬件其实就是一种 IO 操作,软件访问硬件的方式,也就是 I/O 操作的方式有哪些。

硬件在 I/O 上大致分为并行和串行,同时也对应串行接口和并行接口。

随着计算机技术的发展,I/O 控制方式也在不断发展。选择和衡量 I/O 控制方式有如下三条原则

(1) 数据传送速度足够快,能满足用户的需求但又不丢失数据;

(2) 系统开销小,所需的处理控制程序少;

(3) 能充分发挥硬件资源的能力,使 I/O 设备尽可能忙,而 CPU 等待时间尽可能少。

根据以上控制原则,I/O 操作可以分为四类

直接访问:直接访问由用户进程直接控制主存或 CPU 和外围设备之间的信息传送。直接程序控制方式又称为忙/等待方式。
中断驱动:为了减少程序直接控制方式下 CPU 的等待时间以及提高系统的并行程度,系统引入了中断机制。中断机制引入后,外围设备仅当操作正常结束或异常结束时才向 CPU 发出中断请求。在 I/O 设备输入每个数据的过程中,由于无需 CPU 的干预,一定程度上实现了 CPU 与 I/O 设备的并行工作。
上述两种方法的特点都是以 CPU 为中心,数据传送通过一段程序来实现,软件的传送手段限制了数据传送的速度。接下来介绍的这两种 I/O 控制方式采用硬件的方法来显示 I/O 的控制

DMA 直接内存访问:直接内存访问是一种硬件机制,它允许外围设备和主内存之间直接传输它们的I/O数据,而不需要系统处理器的参与。使用这种机制可以大大提高与设备通信的吞吐量。为了进一步减少 CPU 对 I/O 操作的干预,防止因并行操作设备过多使 CPU 来不及处理或因速度不匹配而造成的数据丢失现象,引入了 DMA 控制方式。
通道控制方式:通道,独立于 CPU 的专门负责输入输出控制的处理机,它控制设备与内存直接进行数据交换。有自己的通道指令,这些指令由 CPU 启动,并在操作结束时向 CPU 发出中断信号。

4.解释一下操作系统的主要目的是什么

管理计算机资源,提供一种图形界面,为其他软件提供服务 。 【回答】

操作系统是一种软件,它的主要目的有三种

管理计算机资源,这些资源包括 CPU、内存、磁盘驱动器、打印机等。
提供一种图形界面,就像我们前面描述的那样,它提供了用户和计算机之间的桥梁。
为其他软件提供服务,操作系统与软件进行交互,以便为其分配运行所需的任何必要资源。

5.为什么 Linux 系统下的应用程序不能直接在 Windows 下运行

其中一点是因为 Linux 系统和 Windows 系统的格式不同,格式就是协议,就是在固定位置有意义的数据。Linux 下的可执行程序文件格式是 elf,可以使用 readelf 命令查看 elf 文件头。而 Windows 下的可执行程序是 PE 格式,它是一种可移植的可执行文件。【回答】

还有一点是因为 Linux 系统和 Windows 系统的 API 不同,这个 API 指的就是操作系统的 API,Linux 中的 API 被称为系统调用,是通过 int 0x80 这个软中断实现的。而 Windows 中的 API 是放在动态链接库文件中的,也就是 Windows 开发人员所说的 DLL ,这是一个库,里面包含代码和数据。Linux 中的可执行程序获得系统资源的方法和 Windows 不一样,所以显然是不能在 Windows 中运行的。

6.操作系统结构

6.1单体系统

整个操作系统是以程序集合来编写的,链接在一块形成一个大的二进制可执行程序,这种系统称为单体系统。

6.2分层系统

分层系统使用层来分隔不同的功能单元。每一层只与该层的上层和下层通信。每一层都使用下面的层来执行其功能。层之间的通信通过预定义的固定接口通信。

6.3微内核

内核:是一组中断处理程序的集合,把硬件的能力封装为操作系统功能调用(system calls),用户态程序通过系统调用使用硬件功能,用户态程序运行于各自的进程中,所有用户态进程都共享同一个内核,每当系统调用或中断发生,UNIX 便陷入(trap)内核,内核执行系统调用,与此同时,内核中的分时调度算法将决定把 CPU 交给哪个进程,并管理进程的上下文切换。

微内核:中央内核(微内核本身),周围围绕文件管理、内存管理等功能独立进程,各进程与中央内核通信来完成功能。优点,动态可扩展性强,实时减少或者增加不必要的功能(进程),缺点,要通信需要额外消耗CPU资源。

6.4宏内核

也叫传统内核,就是把基础内核和内存管理、文件管理、设备管理等程序全部放在一起,代码量巨大。

物联网时代,有的计算设备是不需要内存管理或者文件管理的,所以微内核可以解决这个问题。

6.5客户-服务器模式

7.为什么称为陷入内核

如果用户程序想要访问操作系统资源时,会发起系统调用,陷入内核,这样 CPU 就进入了内核态,执行内核代码。至于为什么是陷入,内核是一个凹陷的构造,有陷下去的感觉,所以称为陷入。

8.什么是用户态和内核态

用户态和内核态是操作系统的两种运行状态。 

内核态:处于内核态的 CPU 可以访问任意的数据,包括外围设备,比如网卡、硬盘等,处于内核态的 CPU 可以从一个程序切换到另外一个程序,并且占用 CPU 不会发生抢占情况,一般处于特权级 0 的状态我们称之为内核态。

用户态:处于用户态的 CPU 只能受限的访问内存,并且不允许访问外围设备,用户态下的 CPU 不允许独占,也就是说 CPU 能够被其他程序获取。

那么为什么要有用户态和内核态呢?

这个主要是访问能力的限制的考量,计算机中有一些比较危险的操作,比如设置时钟、内存清理,这些都需要在内核态下完成,如果随意进行这些操作,那你的系统得崩溃多少次。

8.用户态和内核态是如何切换的?

所有的用户进程都是运行在用户态的,但是我们上面也说了,用户程序的访问能力有限,一些比较重要的比如从硬盘读取数据,从键盘获取数据的操作则是内核态才能做的事情,而这些数据却又对用户程序来说非常重要。所以就涉及到两种模式下的转换,即用户态 -> 内核态 -> 用户态,而唯一能够做这些操作的只有系统调用,而能够执行系统调用的就只有操作系统

一般用户态 -> 内核态的转换我们都称之为 trap 进内核,也被称之为 陷阱指令(trap instruction)

他们的工作流程如下:

  1.  首先用户程序会调用 glibc 库,glibc 是一个标准库,同时也是一套核心库,库中定义了很多关键 API。
  2. glibc 库知道针对不同体系结构调用系统调用的正确方法,它会根据体系结构应用程序的二进制接口设置用户进程传递的参数,来准备系统调用。
  3. 然后,glibc 库调用软件中断指令(SWI) ,这个指令通过更新 CPSR 寄存器将模式改为超级用户模式,然后跳转到地址 0x08 处。
  4. 到目前为止,整个过程仍处于用户态下,在执行 SWI 指令后,允许进程执行内核代码,MMU 现在允许内核虚拟内存访问
  5. 从地址 0x08 开始,进程执行加载并跳转到中断处理程序,这个程序就是 ARM 中的 vector_swi()。
  6. 在 vector_swi() 处,从 SWI 指令中提取系统调用号 SCNO,然后使用 SCNO 作为系统调用表 sys_call_table 的索引,调转到系统调用函数。
  7. 执行系统调用完成后,将还原用户模式寄存器,然后再以用户模式执行。
     

9.什么是内核

在计算机中,内核是一个计算机程序,它是操作系统的核心,可以控制操作系统中所有的内容。内核通常是在 boot loader 装载程序之前加载的第一个程序。

10.什么是 boot loader

boot loader 又被称为引导加载程序,能够将计算机的操作系统放入内存中。在电源通电或者计算机重启时,BIOS 会执行一些初始测试,然后将控制权转移到引导加载程序所在的主引导记录(MBR) 。 

一般来说,所有的操作系统的启动流程基本就是:

11.什么是实时系统

实时操作系统对时间做出了严格的要求,实时操作系统分为两种:硬实时和软实时

硬实时操作系统规定某个动作必须在规定的时刻内完成或发生,比如汽车生产车间,焊接机器必须在某一时刻内完成焊接,焊接的太早或者太晚都会对汽车造成永久性伤害。

软实时操作系统虽然不希望偶尔违反最终的时限要求,但是仍然可以接受。并且不会引起任何永久性伤害。比如数字音频、多媒体、手机都是属于软实时操作系统。

你可以简单理解硬实时和软实时的两个指标:是否在时刻内必须完成以及是否造成严重损害。

12.Linux 操作系统的启动过程

二、进程和线程篇

1.多处理系统的优势

多处理系统拥有多个并行的处理器,吞吐量比较高。

2.什么是进程和进程表

进程就是正在执行程序的实例,比如说 Web 程序就是一个进程,shell 也是一个进程,文章编辑器 typora 也是一个进程。

操作系统负责管理所有正在运行的进程,操作系统会为每个进程分配特定的时间来占用 CPU,操作系统还会为每个进程分配特定的资源。

操作系统为了跟踪每个进程的活动状态,维护了一个进程表。在进程表的内部,列出了每个进程的状态以及每个进程使用的资源等。

3.什么是线程

线程是进程的一个实体,是进程的一条执行路径,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。

4.线程和进程的区别

进程是程序的一次运行过程,进程可以看成程序执行的一个实例,进程是系统进行资源分配和调度的一个独立单位。

线程是进程的一个实体,是进程的一条执行路径,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。

5.并发与并行的区别

并行(parallel):指在同一时刻,有多条任务(如指令、进程等)在多个处理器上同时执行,所以无论从微观还是从宏观来看,二者都是一起执行的。

并发(concurrency):指在同一时刻只能有一条指令执行,但多条任务(如指令、进程等)被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。

6.什么是上下文切换

对于单核单线程 CPU 而言,在某一时刻只能执行一条 CPU 指令。上下文切换 (Context Switch) 是一种 将 CPU 资源从一个进程分配给另一个进程的机制。从用户角度看,计算机能够并行运行多个进程,这恰恰是操作系统通过快速上下文切换造成的结果。在切换的过程中,操作系统需要先存储当前进程的状态 (包括内存空间的指针,当前执行完的指令等等),再读入下一个进程的状态,然后执行此进程。

7.使用多线程的好处是什么

  • 能够提高对用户的响应顺序
  • 在流程中的资源共享
  • 比较经济适用
  • 能够对多线程架构有深入的理解

8.进程终止的方式

  • 正常退出(自愿的)
  • 错误退出(自愿的)
  • 严重错误(非自愿的)
  • 被其他进程杀死(非自愿的)

8.1正常退出

多数进程是由于完成了工作而终止。当编译器完成了所给定程序的编译之后,编译器会执行一个系统调用告诉操作系统它完成了工作,这个调用在 UNIX 中是 exit ,在 Windows 中是 ExitProcess

8.2 错误退出

进程发生终止的第二个原因是发现严重错误。例如,如果用户执行如下命令

cc foo.c	

为了能够编译 foo.c 但是该文件不存在,于是编译器就会发出声明并退出。在给出了错误参数时,面向屏幕的交互式进程通常并不会直接退出,因为这从用户的角度来说并不合理,用户需要知道发生了什么并想要进行重试,所以这时候应用程序通常会弹出一个对话框告知用户发生了系统错误,是需要重试还是退出。

8.3严重错误

进程终止的第三个原因是由进程引起的错误,通常是由于程序中的错误所导致的。例如,执行了一条非法指令,引用不存在的内存,或者除数是 0 等。

8.4 被其他进程杀死

某个进程执行系统调用告诉操作系统杀死某个进程。

9.进程间的通信方式

消息传递:消息传递是进程间实现通信和同步等待的机制,使用消息传递,进程间的交流不需要共享变量,直接就可以进行通信;消息传递分为发送方和接收方
先进先出队列:先进先出队列指的是两个不相关联进程间的通信,两个进程之间可以彼此相互进程通信,这是一种全双工通信方式
管道:管道用于两个相关进程之间的通信,这是一种半双工的通信方式,如果需要全双工,需要另外一个管道。
直接通信:在这种进程通信的方式中,进程与进程之间只存在一条链接,进程间要明确通信双方的命名。
间接通信:间接通信是通信双方不会直接建立连接,而是找到一个中介者,这个中介者可能是个对象等等,进程可以在其中放置消息,并且可以从中删除消息,以此达到进程间通信的目的。
消息队列:消息队列是内核中存储消息的链表,它由消息队列标识符进行标识,这种方式能够在不同的进程之间提供全双工的通信连接。
共享内存:共享内存是使用所有进程之间的内存来建立连接,这种类型需要同步进程访问来相互保护。

9.进程间状态模型

9.1进程的三态模型

当一个进程开始运行时,它可能会经历下面这几种状态

  1. 运行态:运行态指的就是进程实际占用 CPU 时间片运行时
  2. 就绪态:就绪态指的是可运行,但因为其他进程正在运行而处于就绪状态
  3. 阻塞态:阻塞态又被称为睡眠态,它指的是进程不具备运行条件,正在等待被 CPU 调度。例如,等待I/O完成、申请缓冲区不能满足、等待信号等

逻辑上来说,运行态和就绪态是很相似的。这两种情况下都表示进程可运行,但是第二种情况没有获得 CPU 时间分片。第三种状态与前两种状态不同的原因是这个进程不能运行,CPU 空闲时也不能运行。

9.2进程的五态模型

在三态模型的基础上,增加了两个状态,即 新建 和 终止 状态。

新建态:进程的新建态就是进程刚创建出来的时候
创建进程需要两个步骤:即为新进程分配所需要的资源和空间,设置进程为就绪态,并等待调度执行。

终止态:进程的终止态就是指进程执行完毕,到达结束点,或者因为错误而不得不中止进程。
终止一个进程需要两个步骤:

先等待操作系统或相关的进程进行善后处理。

然后回收占用的资源并被系统删除。

10.调度算法都有哪些

调度算法分为三大类:批处理中的调度、交互系统中的调度、实时系统中的调度

10.1 批处理中的调度

先来先服务

将按照请求顺序为进程分配 CPU,先请求先分配。

优点:这个算法的强大之处在于易于理解和编程,在这个算法中,一个单链表记录了所有就绪进程。要选取一个进程运行,只要从该队列的头部移走一个进程即可;要添加一个新的作业或者阻塞一个进程,只要把这个作业或进程附加在队列的末尾即可。

缺点:试想一下,如果有 100 个 I/O 进程正在排队,第 101 个是一个 CPU 密集型进程,那岂不是需要等 100 个 I/O 进程运行完毕才会等到一个 CPU 密集型进程运行,这在实际情况下根本不可能,所以需要优先级或者抢占式进程的出现来优先选择重要的进程运行。

最短作业优先

需要注意的是,在所有的进程都可以运行的情况下,最短作业优先的算法才是最优的。
最短剩余时间优先

最短作业优先的抢占式版本被称作为 最短剩余时间优先(Shortest Remaining Time Next) 算法。使用这个算法,调度程序总是选择剩余运行时间最短的那个进程运行。当一个新作业到达时,其整个时间同当前进程的剩余时间做比较。如果新的进程比当前运行进程需要更少的时间,当前进程就被挂起,而运行新的进程。这种方式能够使短期作业获得良好的服务。

10.2 交互式系统中的调度

交互式系统中在个人计算机、服务器和其他系统中都是很常用的。

轮询调度

每个进程都会被分配一个时间段,称为时间片(quantum),在这个时间片内允许进程运行。如果时间片结束时进程还在运行的话,则抢占一个 CPU 并将其分配给另一个进程。如果进程在时间片结束前阻塞或结束,则 CPU 立即进行切换。轮询算法比较容易实现。调度程序所做的就是维护一个可运行进程的列表,就像下图中的 a,当一个进程用完时间片后就被移到队列的末尾,就像下图的 b。

优先级调度

它的基本思想很明确,每个进程都被赋予一个优先级,优先级高的进程优先运行。

但是也不意味着高优先级的进程能够永远一直运行下去,调度程序会在每个时钟中断期间降低当前运行进程的优先级。如果此操作导致其优先级降低到下一个最高进程的优先级以下,则会发生进程切换。

最短进程优先

是以进程的运行时间长度作为优先级,进程运行时间越短,优先级越高。

11.影响调度程序的指标是什么

会有下面几个因素决定调度程序的好坏

  • CPU 使用率:

CPU 正在执行任务(即不处于空闲状态)的时间百分比。

  • 等待时间

这是进程轮流执行的时间,也就是进程切换的时间

  • 吞吐量

单位时间内完成进程的数量

  • 响应时间

这是从提交流程到获得有用输出所经过的时间。

  • 周转时间

从提交流程到完成流程所经过的时间。

12.什么是 RR 调度算法

RR(round-robin) 调度算法主要针对分时系统,RR 的调度算法会把时间片以相同的部分并循环的分配给每个进程,RR 调度算法没有优先级的概念。这种算法的实现比较简单,而且每个线程都会占有时间片,并不存在线程饥饿的问题。

三、内存管理篇

参考:操作系统:内存管理篇—— 虚拟内存、段式内存管理、页式内存管理__索伦的博客-CSDN博客_内存管理篇

1.内存的定义

内存是用于存放数据的硬件。程序执行前需要先放到内存中才能被CPU处理。

 2.物理地址、物理寻址

计算机系统的主存被组织成一个有M个连续的字节大小的单元组成的数组。每字节都有一个唯一的物理地址( Physical Address,PA)。
第一个字节的地址为0,接下来的字节地址为1,再下一个为2,依此类推。给定这种简单的结构,CPU 访问内存的最自然的方式就是使用物理地址。我们把这种方式称为物理寻址( physicaladdressing)。

 3.物理寻址的问题?

在这种情况下,要想在内存中同时运行两个程序是不可能的。如果第一个程序在1的位置写入一个新的值,将会擦掉第二个程序存放在相同位置上的所有内容,所以同时运行两个程序是根本行不通的,这两个程序会立刻崩溃。操作系统如何解决该问题?

4.虚拟地址、虚拟寻址

针对上述问题,提出了虚拟地址、虚拟寻址概念。

我们可以把进程所使用的地址 “隔离” 开来,即让操作系统为每个进程分配独立的一套 「虚拟地址」 ,人人都有,大家自己玩自己的地址就行,互不干涉。但是有个前提每个进程都不能访问物理地址,至于虚拟地址最终怎么落到物理内存里,对进程来说是透明的,操作系统已经把这些都安排的明明白白了。
 

操作系统会提供一种机制,将不同进程的虚拟地址和不同内存的物理地址映射起来。

如果程序要访问虚拟地址的时候,由操作系统转换成不同的物理地址,这样不同的进程运行的时候,写入的是不同的物理地址,这样就不会冲突了。

于是,这里就引出了两种地址的概念:

  1. 我们程序所使用的内存地址叫做虚拟内存地址(Virtual Memory Address)
  2. 实际存在硬件里面的空间地址叫物理内存地址( Physical Memory Address) 。

使用虚拟寻址,CPU通过生成一个虚拟地址(Virtual Address,VA)来访问主存,这个虚拟地址在被送到内存之前先转换成适当的物理地址。将一个虚拟地址转换为物理地址的任务叫做地址翻译(address translation)。

就像异常处理一样,地址翻译需要CPU硬件和操作系统之间的紧密合作。CPU芯片上叫做 内存管理单元(Memory Management Unit,MMU) 的专用硬件,利用存放在主存中的查询表来动态翻译虚拟地址,该表的内容由操作系统管理。图示:

 5.虚拟地址和内存的物理地址映射

主要有两种方式,内存分段和内存分页。

6.是将整个程序一起载入内存当中吗?

不是,程序是由若干个逻辑分段组成的,如可由代码分段、数据分段、栈段、堆段组成。不同的段是有不同的属性的,所以就用分段(Segmentation) 的形式把这些段分离出来。【回答】

7.分段机制下虚拟地址和物理地址如何映射?

分段机制下的虚拟地址由两部分组成,段选择因子和段内偏移量。

  • 段选择因子就保存在段寄存器里面。段选择子里面最重要的是段号,用作段表的索引
  • 段表里面保存的是这个段的基地址、段的界限和特权等级等。
  • 虚拟地址中的段内偏移量应该位于0和段界限之间,如果段内偏移量是合法的,就将段基地址加上段内偏移量得到物理内存地址

 如果要访问段1中偏移量500的虚拟地址,可以计算出它的物理地址为段1基地址2500 + 500 = 3000。

8.分段方法的不足之处

  1. 内存碎片
  2. 内存交换效率低。

9.分段产生内存碎片问题

示例:假设有1G的物理内存,用户执行了多个程序,其中:

  • 游戏占用了512MB;
  • 音乐占用了128MB;
  • 浏览器占用了256MB;

这时候如果终止了音乐这个进程,那么空闲内存还有256MB,但它们是不连续的,这时候就无法再创建一个占用200MB的进程。

图示:

这里的内存碎片的问题共有两处地方:

外部内存碎片,也就是产生了多个不连续的小物理内存,导致新的程序无法被装载;
内部内存碎片,程序所有的内存都被装载到了物理内存,但是这个程序有部分的内存可能并不是很常使用,这也会导致内存的浪费;
针对上面两种内存碎片的问题,解决的方式会有所不同。
解决外部内存碎片的问题就是内存交换

可以将浏览器程序占用的256MB写到硬盘上,再从硬盘上读回到内存上,这时候的这256MB回紧跟随着游戏程序所占用的512MB后面,空出来的剩余空间就是连续的。

10.分段为什么会导致内存交换效率低

对于多进程的系统来说,用分段的方式,内存碎片是很容易产生的,产生了内存碎片,那不得不重新Swap内存区域,这个过程会产生性能瓶颈。

因为硬盘的访问速度要比内存慢太多了,每一次内存交换,我们都需要把一大段连续的内存数据写到硬盘上。
所以,如果内存交换的时候,交换的是一个占内存空间很大的程序,这样整个机器都会显得卡顿。

为了解决内存分段的内存碎片和内存交换效率低的问题,就出现了内存分页

11.内存分页

分段的好处就是能产生连续的内存空间,但是会出现内存碎片和内存交换的空间太大的问题。

要解决这些问题,那么就要想出能少出现一些内存碎片的办法。另外,当需要进行内存交换的时候,让需要交换写入或者从磁盘装载的数据更少一点,这样就可以解决问题了。这个办法,也就是内存分页( Paging) 。

分页是把整个虚拟和物理内存空间切成一段段固定尺寸的大小。这样一个连续并且尺寸固定的内存空间,我们叫页(Page)。在Linux下,每一页的大小为4KB。

虚拟地址与物理地址之间通过页表来映射,如下图:

 页表就是一个页表条目(Page Table Entry, PTE)的数组。虚拟地址空间中的每个页在页表中一个固定偏移量处都有一个PTE。

12.分页机制下虚拟地址和物理地址如何映射

在分页机制下,虚拟地址分为两部分,页号和页内偏移。页号作为页表的索引,页表包含物理页每页所在物理内存的基地址,这个基地址与页内偏移的组合就形成了物理内存地址:

总结,对于一个内存地址转换,其实就是这样三个步骤:

  1. 把虚拟内存地址,切分成页号和偏移量;

  2. 根据页号,从页表里面,查询对应的物理页号;

  3. 直接拿物理页号,加上前面的偏移量,就得到了物理内存地址。

13.分页怎么解决分段的内存碎片、内存交换效率低的问题

由于内存空间都是预先划分好的,也就不会像分段会产生间隙非常小的内存,这正是分段会产生内存碎片的原因。而采用了分页,那么释放的内存都是以页为单位释放的,也就不会产生无法给进程使用的小内存。

如果内存空间不够,操作系统会把其他正在运行的进程中的【最近没被使用】的内存页面给释放掉,也就是暂时写在硬盘上,称为换出(Swap Out)。一旦需要的时候,再加载进来,称为换入(Swap In)。所以,一次性写入磁盘的也只有少数的一个页或者几个页,不会花太多时间,内存交换的效率就相对比较高。

在这里插入图片描述

 分页的方式使得我们在加载程序的时候,不再需要一次性都把程序加载到物理内存中。
我们完全可以在进行虚拟内存和物理内存的页之间的映射之后,并不真的把页加载到物理内存里,而是只有在程序运行中,需要用到对应虚拟内存页里面的指令和数据时,再加载到物理内存里面去。

14.页、页号,页框、页框号,页表、页表项

段、页、页框、页表、页表项_biggerbugger的博客-CSDN博客_页大小和页框大小

15.分页上的缺陷

因为操作系统是可以同时运行非常多的进程的,那这就意味着页表会非常的庞大

在 32 位的环境下,虚拟地址空间共有 4GB,假设一个页的大小是 4KB(2^12),那么就需要大约 100 万 (2^20) 个页,每个「页表项」需要 4 个字节大小来存储,那么整个 4GB 空间的映射就需要有 4MB 的内存来存储页表。

这 4MB 大小的页表,看起来也不是很大。但是要知道每个进程都是有自己的虚拟地址空间的,也就说都有自己的页表。

那么,100 个进程的话,就需要 400MB 的内存来存储页表,这是非常大的内存了,更别说 64 位的环境了。

16.多级页表

要解决上面的问题,就需要采用的是一种叫作多级页表(Multi-Level Page Table)的解决方案。

17.TLB

多级页表虽然解决了空间上的问题,但是虚拟地址到物理地址的转换就多了几道转换的工序,这显然就降低了这俩地址转换的速度,也就是带来了时间上的开销。

程序是有局部性的,即在一段时间内,整个程序的执行仅限于程序中的某一部分。相应地,执行所访问的存储空间也局限于某个内存区域。

在这里插入图片描述

 利用这一特性,把最常访问的几个页表项存储到访问速度更快的硬件,于是计算机科学家们,就在 CPU 芯片中,加入了一个专门存放程序最常访问的页表项的 Cache,这个 Cache 就是 TLB(Translation Lookaside Buffer) ,通常称为页表缓存、转址旁路缓存、快表等。

在 CPU 芯片里面,封装了内存管理单元(Memory Management Unit)芯片,它用来完成地址转换和 TLB 的访问与交互。

有了 TLB 后,那么 CPU 在寻址时,会先查 TLB,如果没找到,才会继续查常规的页表。

TLB 的命中率其实是很高的,因为程序最常访问的页就那么几个。

在这里插入图片描述

18.物理地址、逻辑地址、线性地址、虚拟地址的区别

  • 虚拟地址:指的是由程序产生的由段选择符和段内偏移地址两个部分组成的地址。为什么叫它是虚拟的地址呢?因为这两部分组成的地址并没有直接访问物理内存,而是要通过分段地址的变换机构处理或映射后才会对应到相应的物理内存地址。
  • 逻辑地址:指由程序产生的与段相关的偏移地址部分。不过有些资料是直接把逻辑地址当成虚拟地址,两者并没有明确的界限。
  • 线性地址:指的是虚拟地址到物理地址变换之间的中间层,是处理器可寻指的内存空间(称为线性地址空间)中的地址。程序代码会产生逻辑地址,或者说是段中的偏移地址,加上相应段的基地址就生成了一个线性地址。如果启用了分页机制,那么线性地址可以再经过变换产生物理地址。若是没有采用分页机制,那么线性地址就是物理地址。
  • 物理地址:指的是现在CPU外部地址总线上的寻址物理内存的地址信号,是地址变换的最终结果。

19.什么是按需分页

在操作系统中,进程是以页为单位加载到内存中的,按需分页是一种虚拟内存的管理方式。在使用请求分页的系统中,只有在尝试访问页面所在的磁盘并且该页面尚未在内存中时,也就发生了缺页异常,操作系统才会将磁盘页面复制到内存中。【回答】

20.什么是虚拟内存

虚拟内存是一种内存分配方案,是一项可以用来辅助内存分配的机制。我们知道,应用程序是按页装载进内存中的。但并不是所有的页都会装载到内存中,计算机中的硬件和软件会将数据从 RAM 临时传输到磁盘中来弥补内存的不足。如果没有虚拟内存的话,一旦你将计算机内存填满后,计算机会对你说呃,不,对不起,您无法再加载任何应用程序,请关闭另一个应用程序以加载新的应用程序。对于虚拟内存,计算机可以执行操作是查看内存中最近未使用过的区域,然后将其复制到硬盘上。虚拟内存通过复制技术实现了 妹子,你快来看哥哥能装这么多程序 的资本。复制是自动进行的,你无法感知到它的存在。

21.虚拟内存的实现方式

虚拟内存中,允许将一个作业分多次调入内存。釆用连续分配方式时,会使相当一部分内存空间都处于暂时或永久的空闲状态,造成内存资源的严重浪费,而且也无法从逻辑上扩大内存容量。因此,虚拟内存的实需要建立在离散分配的内存管理方式的基础上。虚拟内存的实现有以下三种方式:

  • 请求分页存储管理。
  • 请求分段存储管理。
  • 请求段页式存储管理。

不管哪种方式,都需要有一定的硬件支持。一般需要的支持有以下几个方面:

  • 一定容量的内存和外存。
  • 页表机制(或段表机制),作为主要的数据结构。
  • 中断机构,当用户程序要访问的部分尚未调入内存,则产生中断。
  • 地址变换机构,逻辑地址到物理地址的变换。

22.空闲内存管理的方式

操作系统在动态分配内存时(malloc,new),需要对空间内存进行管理。一般采用了两种方式:位图和空闲链表。

1.使用位图进行管理

使用位图方法时,内存可能被划分为小到几个字或大到几千字节的分配单元。每个分配单元对应于位图中的一位,0 表示空闲, 1 表示占用(或者相反)。一块内存区域和其对应的位图如下。

图 a 表示一段有 5 个进程和 3 个空闲区的内存,刻度为内存分配单元,阴影区表示空闲(在位图中用 0 表示);图 b 表示对应的位图;图 c 表示用链表表示同样的信息。

分配单元的大小是一个重要的设计因素,分配单位越小,位图越大。然而,即使只有 4 字节的分配单元,32 位的内存也仅仅只需要位图中的 1 位。32n 位的内存需要 n 位的位图,所以1 个位图只占用了 1/32 的内存。如果选择更大的内存单元,位图应该要更小。如果进程的大小不是分配单元的整数倍,那么在最后一个分配单元中会有大量的内存被浪费。

位图提供了一种简单的方法在固定大小的内存中跟踪内存的使用情况,因为位图的大小取决于内存和分配单元的大小。这种方法有一个问题,当决定为把具有 k 个分配单元的进程放入内存时,内容管理器(memory manager) 必须搜索位图,在位图中找出能够运行 k 个连续 0 位的串。在位图中找出制定长度的连续 0 串是一个很耗时的操作,这是位图的缺点。(可以简单理解为在杂乱无章的数组中,找出具有一大长串空闲的数组单元)。

2.使用空闲链表

另一种记录内存使用情况的方法是,维护一个记录已分配内存段和空闲内存段的链表,段会包含进程或者是两个进程的空闲区域。可用上面的图 c 来表示内存的使用情况。链表中的每一项都可以代表一个 空闲区(H) 或者是进程(P)的起始标志,长度和下一个链表项的位置。

23.页面置换算法都有哪些

在地址映射过程中,如果在页面中发现所要访问的页面不在内存中,那么就会产生一条缺页中断。当发生缺页中断时,如果操作系统内存中没有空闲页面,那么操作系统必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。而用来选择淘汰哪一页的规则叫做页面置换算法。

最佳置换算法

先进先出置换算法

最近最久未使用算法

时钟置换算法

四、文件系统篇

文件系统是操作系统中负责管理持久数据的子系统,说简单点,就是负责把用户的文件存到磁盘硬件中,因为即使计算机断电了,磁盘里的数据并不会丢失,所以可以持久化的保存文件。

1.提高文件系统性能的方式

 访问磁盘的效率要比内存慢很多,所以磁盘优化是很有必要的,下面我们会讨论几种优化方式

1.1 高速缓存

最常用的减少磁盘访问次数的技术是使用 块高速缓存(block cache) 或者 缓冲区高速缓存(buffer cache)

管理高速缓存有不同的算法,常用的算法是:检查全部的读请求,查看在高速缓存中是否有所需要的块。如果存在,可执行读操作而无须访问磁盘。如果检查块不再高速缓存中,那么首先把它读入高速缓存,再复制到所需的地方。之后,对同一个块的请求都通过高速缓存来完成。

1.2 块提前读

第二个明显提高文件系统的性能是在需要用到块之前试图提前将其写入高速缓存从而提高命中率。许多文件都是顺序读取。如果请求文件系统在某个文件中生成块 k,文件系统执行相关操作并且在完成之后,会检查高速缓存,以便确定块 k + 1 是否已经在高速缓存。如果不在,文件系统会为 k + 1 安排一个预读取,因为文件希望在用到该块的时候能够直接从高速缓存中读取。

当然,块提前读取策略只适用于实际顺序读取的文件。对随机访问的文件,提前读丝毫不起作用。甚至还会造成阻碍。

1.3 减少磁盘臂运动

高速缓存和块提前读并不是提高文件系统性能的唯一方法。另一种重要的技术是把有可能顺序访问的块放在一起,当然最好是在同一个柱面上,从而减少磁盘臂的移动次数

1.4 磁盘碎片整理

在初始安装操作系统后,文件就会被不断的创建和清除,于是磁盘会产生很多的碎片,在创建一个文件时,它使用的块会散布在整个磁盘上,降低性能。删除文件后,回收磁盘块,可能会造成空穴。

磁盘性能可以通过如下方式恢复:移动文件使它们相互挨着,并把所有的至少是大部分的空闲空间放在一个或多个大的连续区域内。Windows 有一个程序 defrag 就是做这个事儿的。Windows 用户会经常使用它,SSD 除外。

磁盘碎片整理程序会在让文件系统上很好地运行。Linux 文件系统(特别是 ext2 和 ext3)由于其选择磁盘块的方式,在磁盘碎片整理上一般不会像 Windows 一样困难,因此很少需要手动的磁盘碎片整理。而且,固态硬盘并不受磁盘碎片的影响,事实上,在固态硬盘上做磁盘碎片整理反倒是多此一举,不仅没有提高性能,反而磨损了固态硬盘。所以碎片整理只会缩短固态硬盘的寿命。

2.磁盘基本知识

磁盘由多个盘片组成,每个盘片的基本结构为:

各标识含义:

  • A是磁道,多个磁盘的同一个磁道重叠起来叫做柱面,它包含了很多个扇区。
  • B是几何上的扇区,只做标示,此处无特殊含义。
  • C是扇区,扇区是磁盘的最小组成单元,通常是512字节(有的磁盘时4096字节)。
  • D是磁盘块(簇),块/簇是操作系统虚拟出来的概念,它由多个扇区组成。

读取磁盘数据时,磁盘上的磁头不断旋转变道,然后读取数据。因此寻道时间越短,I/O操作越快,目前磁盘的平均寻道时间一般在3-15ms,一般都在10ms左右。

3.为什么存在磁盘块?(簇)

  1. 读取方便:由于扇区的数量比较小,数目众多在寻址时比较困难,所以操作系统就将相邻的扇区组合在一起,形成一个块,再对块进行整体的操作。
  2. 分离对底层的依赖:操作系统忽略对底层物理存储结构的设计。通过虚拟出来磁盘块的概念,在系统中认为块是最小的单位。

我们平常所说的4K对齐也就是指的块大小,它表示操作系统读取磁盘时一次读取的数据大小。如果操作系统一次读取4K,但是块大小只有2K,就相当于一次IO要做2次磁盘寻址。而如果磁盘块大小刚好也是4K,那么一次IO就只需一次寻址。相对而言,磁盘寻址效率是很低的,多一次磁盘寻址肯定会更加导致IO效率低,因此对磁盘进行4K对齐也是提高了系统的IO性能。

4.磁盘臂调度算法

一般情况下,影响磁盘快读写的时间由下面几个因素决定:

寻道时间 - 磁头从开始移动到数据所在磁道所需要的时间;
旋转延迟 - 盘片旋转将请求数据所在扇区移至读写磁头下方所需要的时间,旋转延迟取决于磁盘转速;
实际数据的读取或者写入时间-完成传输所请求的数据所需要的时间。
这三种时间参数也是磁盘寻道的过程。一般情况下,寻道时间对总时间的影响最大,所以,有效的降低寻道时间能够提高磁盘的读取速度。

4.1先来先服务算法(FCFS)

算法思想:根据进程请求访问磁盘的先后顺序进行调度。

优点:公平;如果请求访问的磁道比较集中的话,算法性能还算可以
缺点:如果大量进程竞争使用磁盘,请求访问的磁道很分散,FCFS在性能上很差,寻道时间长

假设磁头的初始位置是100号磁道,有多个进程先后陆续地请求访问55、58、39、18、90、160、150、38、184号磁道。按照先来先服务算法规则,按照请求到达的顺序,磁头需要一次移动到55、58、39、18、90、160、150、38、184号磁道。

img

 磁头共移动了 45 + 3 + 19 + 21 + 72 + 70 + 10 + 112 + 146 = 498个磁道。响应一个请求平均需要移动498 / 9 = 55.3个磁道(平均寻找长度)。

4.2 最短寻找时间优先(SSTF)

算法思想:优先处理的磁道是与当前磁头最近的磁道。可以保证每次寻道时间最短,但是不能保证总的寻道时间最短。(其实是贪心算法的思想,只是选择眼前最优,但是总体未必最优)。

缺点:可能产生饥饿现象

假设磁头的初始位置是100号磁道,有多个进程先后陆续地请求访问55、58、39、18、90、160、150、38、184号磁道。

img

 磁头总共移动了(100 -18)+ (184 -18) = 248个磁道。响应一个请求平均需要移动248 / 9 = 27.5个磁道(平均寻找长度)。
本例中,如果在处理18号磁道的访问请求时又来了一个38号磁道的访问请求,处理38号磁道的访问请求又来了一个18号磁道访问请求。如果有源源不断的18号、38号磁道访问请求,那么150、160、184号磁道请求的访问就永远得不到满足,从而产生饥饿现象。这里产生饥饿的原因是磁头在一小块区域来回移动。

 4.3 扫描算法(SCAN)

第一种:电梯算法(LOOK算法)

一扫到底,然后依次扫回来去。

假设某磁盘的磁道为0~200号,磁头的初始位置是100号磁道,且此时磁头正在往磁道号增大的方向移动,有多个进程先后陆续的访问55、58、39、18、90、160、150、38、184号磁道。

img

 磁头共移动了(184 - 100)+ (184 -18) = 250个磁道。响应一个请求平均需要移动 250 / 9 = 27.5个磁道(平均寻找长度)。

第二种:循环扫描算法

循环扫描(C-SCAN)调度是 SCAN 的一个变种,以提供更均匀的等待时间。像 SCAN 一样,C-SCAN 移动磁头从磁盘一端到磁盘另一端,并且处理行程上的请求。然而,当磁头到达另一端时,它立即返回到磁盘的开头,而并不处理任何回程上的请求。(一扫到底,然后迅速回到首柱面,再依次往后扫)

5.RAID 的不同级别

RAID 称为 磁盘冗余阵列,简称 磁盘阵列。利用虚拟化技术把多个硬盘结合在一起,成为一个或多个磁盘阵列组,目的是提升性能或数据冗余。

RAID 有不同的级别

RAID 0 - 无容错的条带化磁盘阵列
RAID 1 - 镜像和双工
RAID 2 - 内存式纠错码
RAID 3 - 比特交错奇偶校验
RAID 4 - 块交错奇偶校验
RAID 5 - 块交错分布式奇偶校验
RAID 6 - P + Q冗余

五、IO 篇

参考:设备管理_KerberosHell的博客-CSDN博客

1.什么是IO设备

I/O设备就是可以将数据输入到计算机,或者可以接收计算机输出数据的外部设备。

在Linux中:

UNIX系统将外部设备抽象为一种特殊的文件,用户可以使用与文件操作相同的方式对外部设备进行操作。

Write操作:向外部设备写出数据。

Read操作:从外部设备读入数据。

2.IO设备的分类

举例1

人机交互类外部设备:数据传输速度较快 鼠标 键盘 打印机

存储设备:数据传输速率较快 移动硬盘光盘等

网络通信设备:数据传输速率在两者之间 调制解调器

举例2

低速设备:鼠标、键盘等------传输速率为每秒几个到几百字节

中速设备:如激光打印机等-------传输速率为每秒数千至上万个字节

高速设备:如磁盘等-------传输速率为每秒数千字节至千兆字节的设备

举例3

块设备:如磁盘等-------数据传输的基本单位是

字符设备:鼠标、键盘等-------数据传输的基本单位是字符

3.I/O控制器硬件组成

I/0设备由机械部件和电子部件(I/0控制器)

I/0设备的机械部件
I/O设备的机械部件主要用来执行具体I/0操作。
如我们看得见摸得着的鼠标/键盘的按钮; 显示器的LED屏; 移动硬盘的磁臂、磁盘盘面。

I/0设备的电子部件(I/0控制器)

I/O设备的电子部件通常是一块插入主板扩充槽的印刷电路板。
CPU无法直接控制I/O设备的机械部件,因此I/0设 备还要有一个电子部件作为CPU和I/O设备机械部件之间的中介,用于实现CPU对设备的控制。

4.I/O控制器功能

  1. 如CPU发来的read/write命令,I/O控制器中会有相应的控制寄存器先来存放命令和参数
  2. I/0控制器中会有相应的状态寄存器,用于记录I/O设备的当前状态。如: 1表示空闲,0表示忙碌
  3. I/0控制器中会设置相应的数据寄存器。输出时,数据寄存器用于暂存CPU发来的数据,之后再由控制器传送设备。输入时,数据寄存器用于暂存设备发来的数据,之后CPU从数据寄存器中取走数据。
  4. 类似于内存的地址,为了区分设备控制器中的各个寄存器,也需要给各个寄存器设置一个特定的“地址”。I/O控制器通过CPU提供的“地址”来判断CPU要读/写的是哪个寄存器。

5.I/O控制器的组成

 I/O逻辑负责接收和识别CPU的各种命令( 如地址译码),并负责对设备发出命令

一个I/O控制器可能会对应多个设备;

数据寄存器、控制寄存器、状态寄存器可能有多个(如:每个控制/状态寄存器对应一个具体的设备),且这些寄存器都要有相应的地址,才能方便CPU操作。

有的计算机会让这些寄存器占用内存地址的一部分, 称为内存映像I/O;

另一些计算机则采用I/O专用地址,即寄存器独立编址

6.内存映像I/O && 寄存器独立编制

  • 内存映像I/O

  •  寄存器独立编址

 7.I/O控制方式

 7.1 程序直接控制方式

7.2 中断驱动方式

引入中断机制。由于I/O设 备速度很慢,因此在CPU发出读/写命令后,可将等待I/O的进程阻塞,先切换到别的进程执行。当I/O完成后,控制器会向CPU发出一个中断信号,CPU检测到中断信号后,会保存当前进程的运行环境信息,转去执行中断处理程序处理该中断。处理中断的过程中,CPU从I/O控制器读一个字的数据传送到CPU寄存器,再写入主存。接着,CPU恢复等待I/O的进程(或其他进程)的运行环境,然后继续执行。

7.3 DMA方式

与中断驱动方式相比,DMA方式 ( Direct Memory Access,直接存储器存取。主要用于块设备的I/O控制) 有这样几个改进:

​ ①数据的传送单位是“块”。不再是一个字、一个字的传送;
​ ②数据的流向是从设备直接放入内存,或者从内存直接到设备。不再需要CPU作为“快递小哥”。
​ ③仅在传送一个或多个数据块的开始和结束时,才需要CPU干预。

7.4 通道控制方式

与CPU相比,通道可以执行的指令很单一,并且通道程序是放在主机内存中的,也就是说通道与CPU共享内存,CPU干预的频率极低,通道会根据CPU的指示执行相应的通道程序,只有完成一组数据块的读/写后才需要发出中断信号,请求CPU干预。

数据传送的单位:每次读/写一组数据块

数据的流向(在通道的控制下进行)

读操作(数据输入) : I/O设备 → 内存
写操作(数据输出) :内存 → I/O设备

主要缺点和主要优点

缺点:实现复杂,需要专门的通道硬件支持
优点: CPU、 通道、I/O设备可并行工作,资源利用率很高。
一个通道可以控制多个I/O控制器

7.5 总结

8. I/O软件层次结构

 用户层软件:用户可以直接使用该层提供的、与I/O操作相关的库函数对设备进行操作

设备独立性软件:与设备的硬件特性无关的功能几乎都在这一层实现。

1.向上层提供统一 的调用接口(如read/write系统调用)

2.设备的保护

3.差错处理

4.设备的分配与回收

5.数据缓冲区管理

可以通过缓冲技术屏蔽设备之间数据交换单位大小和传输速度的差异

6.建立逻辑设备名到物理设备名的映射关系;根据设备类型选择调用相应的驱动程序I/O核心子系统

用户或用户层软件发出I/0操作相关系统调用的系统调用时,需要指明此次要操作的1I/O设备的逻辑设备名
设备独立性软件需要通过逻辑设备表(LUT, Logical Unit Table)来确定逻辑设备对应的物理设备,并找到该设备对应的设备驱动程序。

操作系统系统可以采用两种方式管理逻辑设备表(LUT) :

第一种方式,整个系统只设置一张LUT,这就意味着所有用户不能使用相同的逻辑设备名,因此这种方式只适用于单用户操作系统。

​ 第二种方式,为每个用户设置一张LUT,各个用户使用的逻辑设备名可以重复,适用于多用户操作系统。系统会在用户登录时为其建立一个用户管理进程,而LUT就存放在用户管理进程的PCB中。

设备驱动程序

主要负责对硬件设备的具体控制,将上层发出的一系列命令( 如read/write) 转化成特定设备“能听得懂”的一系列操作。包括设置设备寄存器:检查设备状态等

驱动程序一般会 以一个独立进程的方式存在。

中断处理程序

当I/0任务完成时,I/O控制器会发送一个中断信号,系统会根据中断信号类型找到相应的中断处理程序并执行。中断处理程序的处理流程如下:

9.假脱机技术

为什么称为“脱机”——脱离主机的控制进行的输入/输出操作。假脱机技术”,又称“SPOOLing 技术”是用软件的方式模拟脱机技术。引入脱机技术后,缓解了CPU与慢速I/O设备的速度矛盾

10.假脱机技术 —— 输入井和输出井

 假脱机技术”,又称“SPOOLing 技术”是用软件的方式模拟脱机技术。 SPOOLing 系统的组成如下

 在磁盘上开辟出两个存储区域——“输入井”和“输出井”

“输入井”模拟脱机输入时的磁带,用于收容I/O设备输入的数据
输出井”模拟脱机输出时的磁带,用于收容用户进程输出的数据

输入进程”模拟脱机输入时的外围控制机
输出进程”模拟脱机输出时的外围控制机

在输入进程的控制下,“输入缓冲区”用于暂存从输入设备输入的数据,之后再转存到输入井中
在输出进程的控制下,“输出缓冲区”用于暂存从输出井送来的数据,之后再传送到输出设备上
在这里插入图片描述

缓冲区管理

11.什么是缓冲区?

缓冲区是一个存储区域,可以由专门的硬件寄存器组成,也可利用内存作为缓冲区。

使用硬件作为缓冲区的成本较高,容量也较小,一般仅用在对速度要求非常高的场合(如存储器管理中所用的联想寄存器,由于对页表的访问频率极高,因此使用速度很快的联想寄存器来存放页表项的副本)

一般情况下, 更多的是利用内存作为缓冲区,设备独立性软件 的缓冲区管理就是要组织管理好这些缓冲区

12.缓冲区的作用

在这里插入图片描述

六、死锁篇

1、什么是死锁

所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。

2.产生死锁的原因

(1) 因为系统资源不足,资源竞争。
(2) 进程运行推进的顺序不合适。

  • 若P1保持了资源R1,P2保持了资源R2,系统处于不安全状态,因为这两个进程再向前推进,便可能发生死锁
  • 例如,当P1运行到P1:Request(R2)时,将因R2已被P2占用而阻塞;当P2运行到P2:Request(R1)时,也将因R1已被P1占用而阻塞,于是发生进程死锁

3.产生死锁的四个必要条件:

       (1) 互斥条件:一个资源每次只能被一个进程使用。
  (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  (3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
  (4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

4.什么是僵尸进程

僵尸进程是已完成且处于终止状态,但在进程表中却仍然存在的进程。僵尸进程通常发生在父子关系的进程中,由于父进程仍需要读取其子进程的退出状态所造成的。

5.死锁的解决方法或者处理

预防:通过设置某些限制条件,以破坏产生死锁的四个条件中的一个或者几个,来防止发生死锁。
避免:系统在分配资源时根据资源的使用情况提前作出预测,从而避免死锁的发生。
检测:允许系统在运行的过程中产生死锁,但是,系统中有相应的管理模块可以及时检测出已经产生的死锁,并且精确地确定与死锁有关的进程和资源,然后采取适当措施,清除系统中已经产生的死锁。
解除:与检测死锁相配套的一种措施,用于将进程从死锁状态下解脱出来。

解决死锁的具体描述:

预防死锁
根据死锁产生的四个必要条件,只要使用其中之一不能成立,死锁就不会出现。但必要条件①是由设备的固有特性所决定的,不仅不能改变,相反还应加以保证,因此实际上只有三种方法:

资源一次性分配:一次性分配所有资源,这样就不会再有请求了,只要有一个资源得不到分配,也不给这个进程分配其他的资源:(破坏请求条件)
可剥夺资源:即当某进程获得了部分资源,一但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件)
资源有序分配法系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件)


避免死锁
避免死锁,它是在进程请求分配资源时,采用某种算法(银行家算法)来预防可能发生的死锁,从而拒绝可能引起死锁的某个资源请求。

在避免死锁(或银行家算法)中必须谈到两种系统状态:
安全状态,指系统能按照某种顺序,为每个进程分配所需的资源,直至最大需求,使得每个进程都能顺利完成。
非安全状态:即在某个时刻系统中不存在一个安全序列,则称系统处于不安全状态或非安全状态。
虽然并非所有不安全状态都是死锁状态,但当系统进入不安全状态后,便有可能进入死锁状态;反之只要系统处于安全状态,系统便可避免进入死锁状态。因此,避免死锁的实质是如何使系统不进入不安全状态。
 

检测死锁
通过使用软件工具来检测死锁:

  • Jstack命令

jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用于打印出给定的java进程ID或核心文件或远程调试服务的Java堆栈信息。 Jstack工具可以用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。

  • JConsole工具

Jconsole是JDK自带的监控工具,在JDK/bin目录下可以找到。它用于连接正在运行的本地或者远程的JVM,对运行在Java应用程序的资源消耗和性能进行监控,并画出大量的图表,提供强大的可视化界面。而且本身占用的服务器内存很小,甚至可以说几乎不消耗

解除死锁
当发现有进程死锁后,便应立即把它从死锁状态中解脱出来,常采用的方法有:

剥夺资源:从其它进程剥夺足够数量的资源给死锁进程,以解除死锁状态;
撤消进程:可以直接撤消死锁进程或撤消代价最小的进程,直至有足够的资源可用,死锁状态消除为止;所谓代价是指优先级、运行代价、进程的重要性和价值等。

6.死锁的恢复方式

上述,解除死锁

参考:
————————————————
版权声明:本文为CSDN博主「KerberosHell」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44075132/article/details/116247358

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值