秋招准备之——计算机操作系统

秋招复习笔记系列目录(不断更新中):

  • 1.数据结构全系列
  • 2.计算机网络知识整理(一)
  • 3.计算机网络知识整理(二)
  • 4. Java虚拟机知识整理
  • 5.计算机操作系统
  • 6.深入理解HashMap
  • 7.深入理解ConcurrentHashMap
  • 8.MySQL**

一、操作系统概述

1.1 操作系统的基本概念

1. 概念

操作系统是指控制和管理整个计算机系统的硬件和软件资源,并合理地组织调度计算机的工作和资源的分配,以提供给用户和其他软件方便的接口和环境的程序集合。

2. 操作系统的特征

两个最基本的特征:

  • 并发: 指两个或多个事件在同一时间间隔内发生。操作系统的并发性是指计算机系统中同时存在多个运行着的程序,因此操作系统具有处理和调度多个程序同时执行的能力。引入进程的目的是使程序能并发执行
  • 共享: 指系统中的资源可供内存中多个并发执行的进程共同使用。分为两种方式:
    • 互斥共享: 在一段时间内只允许一个进程访问资源。一段时间内只允许一个进程访问的资源称为临界资源或独占资源
    • 同时访问方式: 允许一段时间内由多个进程“同时”访问,同时是宏观的,微观上,可能是交替执行的

其他特征:

  • 虚拟: 指把一个物理上的实体变为若干个逻辑上的对应物。虚拟技术可以分为时分复用技术和空分复用技术。
  • 异步: 多道程序环境下,允许多个程序并发执行,但由于资源有限,进程的执行不是一贯到底,而是走走停停,以不可预知的速度向前推进。

3. 操作系统的目标和功能

  • 计算机系统资源管理: 包括对以下资源的管理:
    • 处理机管理: 即对进程的管理,包括进程的创建、销毁、冲突避免等。主要功能包括进程控制、进程同步、进程通信、死锁处理、处理机调度等。
    • 存储器管理: 主要包括内存分配、地址映射、内存保护与共享、内存扩充
    • 文件管理: 即文件系统的管理,包括文件存储空间的管理、目录管理以及文件读写管理和保护。
    • 设备管理: 主要任务是完成I/O请求,方便用户使用各种设备,提高设备的利用率。主要包括缓冲管理、设备分配、设备处理和虚拟设备等。
  • 作为用户与计算机硬件系统之间的接口: 提供接口给用户使用,包括命令接口和程序接口:
    • 命令接口: 用户利用操作命令来组织和控制作业执行
    • 程序接口: 编程人员使用编程接口来请求操作系统服务。
  • 用作扩充机器: 覆盖了软件的机器称为扩充机器,又称为虚拟机。

1.2 操作系统的运行环境

1.操作系统的运行机制

  • 操作系统内核的内容:
    • ①时钟管理: 对系统时间的管理,一方面用于计时,另一方面通过时钟中断管理,实现进程切换。
    • ②中断机制: 在系统中起通信网络的作用,以协调外部事件的响应和处理。
    • ③原语: 将具有以下特点的底层公用小程序称为原语:
      • 处于操作系统最底层
      • 运行具有原子性
      • 运行时间很短且调用频繁
    • ④系统控制的数据结构及处理: 包括一些用来登记状态信息的数据结构,以及进行诸如进程管理、存储器管理、设备管理等的操作。

2.中断和异常

用户态和核心态的切换,需要用到中断或异常实现,包括两种类型:

  • 外中断(中断): 来自CPU执行指令以外的事件的发生,如设备发出的I/O结束中断、时钟中断等。
  • 内中断(异常): 来自CPU执行指令内部的事件,如程序的非法操作码、地址越界等事件。
  • 陷阱: 在用户程序中使用系统调用

3.系统调用

系统调用命令按照功能分为:设备管理、文件管理、进程控制、进程通信、内存管理

总结: 系统运行环境可以理解为,用户通过操作系统运行上层程序,而上层程序依赖于操作系统底层管理和程序提供服务支持,当需要管理程序服务时,系统则通过硬件中断机制或异常处理进入核心态。当管理程序结束时,通过相应的保存程序现场退出中断处理程序或异常处理程序,返回中断点,继续执行上层程序。
在这里插入图片描述

1.4 操作系统的体系结构——大内核和微内核

  • 大内核: 大内核是将操作系统主要功能模块都作为一个紧密结合的整体运行在核心态,具有很高的性能。
  • 微内核: 由于操作系统不断复杂,因此将一部分操作系统功能移出内核,从而降低内核的复杂性。移出的部分根据分层的原则划分成若干服务,相互独立。在微内核结构下,操作系统被划分成小的、定义良好的模块,只有微内核这一个模块运行在内核态,其余模块运行在用户态。因为需要频繁地在用户态和核心态之间进行切换,所以会有一定的性能损失。

二、进程管理

2.1 进程和线程

1.进程

  • 基础概念:
    • 进程控制块: 为了使参与并发执行的程序(含数据)能独立运行,必须为之配置一个专门的数据结构,称为进程控制块(PCB)。系统利用PCB来描述进程的基本情况和运行状态,进而控制和管理进程。
    • 进程映像: 程序段、相关数据段和PCB构成进程映像(进程实体)
  • 进程的概念: 程序的一次执行过程,或者说,是进程实体的一次运行过程,是系统进行资源分配和调度的一个独立单位
  • 进程的特征:
    • ①动态性: 是进程的最基本特征。进程是程序的一次执行,有着创建、活动、暂停、终止等过程,具有一定的生命周期,是动态地产生、变化和消亡的。
    • ②并发性: 多个进程在一段时间内能同时执行。引入进程的目的就是为了程序与其他进程的程序并发执行,以提高资源利用率
    • ③独立性: 进程实体是一个能独立运行、独立获得资源和独立接收调度的基本单位。
    • ④异步性: 由于进程的相互制约,使进程具有执行的间断性,即按照各自独立的、不可预知的速度向前推进。异步性会导致执行结果的不可再现性,因此在操作系统中必须配置相应的进程同步机制。
    • ⑤结构性: 每个进程都要配置一个PCB对其进行描述,从结构上看,进程实体是由程序段、数据段和进程段三部分组成的。

2.进程的状态和转换

进程通常有以下五种状态:

  • ①运行状态: 进程在处理机上运行
  • ②就绪状态: 进程获得了除处理机之外的一切所需资源,一旦得到处理机即可运行
  • ③阻塞状态: 又称等待状态,进程正在等待某一事件而暂停,如等待资源可用或输入输出完成等
  • ④创建状态: 进程正在被创建,尚未转到就绪状态。创建的步骤为:申请PCB->向PCB中填写控制管理进程的信息->系统分配资源->将进程转到就绪状态
  • ⑤结束状态: 正在退出,结束运行
    秋招准备之——计算机操作系统_第1张图片

3.进程控制

进程控制包括进程创建、进程终止、进程阻塞和唤醒、进程切换

  • 进程创建(创建原语): 进程的创建如下:

    • ①为进程分配一个进程ID,并申请一个空白的PCB
    • ②为进程分配资源,为新进程的程序和数据,以及用户栈分配必要的内存空间。如果内存空间不足,会进入阻塞状态而不是创建失败
    • ③初始化PCB,主要包括初始化标志信息,初始化处理机状态信息和控制信息,以及设置进程的优先级。
    • ④进入进程就绪队列,等待被调度。
  • 进程终止(撤销原语): 引起进程终止的情况有正常结束异常结束两种。进程终止的过程为:

    • 根据进程ID,检索PCB,从中读出进程的状态
    • 若终止进程处于执行状态,立即终止执行,并将资源分给其他进程
    • 若终止进程还有子进程,则应使其所以子进程终止
    • 将进程拥有的所有资源,归还给父进程或操作系统
    • 将PCB从所在队列中删除
  • 进程的阻塞和唤醒

    阻塞的过程为:

    • 找到要阻塞进程的ID及PCB
    • 若进程为运行状态,则保护现场,并将其标志为阻塞状态,停止其运行
    • 将PCB插入等待队列中

    唤醒的过程:

    • 找到唤醒进程的ID及PCB
    • 将其从等待队列中移除,设置为就绪状态
    • 将PCB插入就绪队列中,等待调度程序调度
  • 进程切换: 指处理机从一个进程的运行状态转到另一个进程上运行,过程如下:

    • 保存处理机上下文、包括程序计数器和其他寄存器
    • 更新PCB信息
    • 把进程的PCB移入相应队列,如就绪、等待
    • 选择另一个进程执行,并更新其PCB
    • 更新内存管理的数据结构
    • 恢复处理机上下文

4.进程的组成

进程一般由三个部分组成:

  • 进程控制块(PCB): PCB是描述进程基本情况和运行状态的数据结构,是进程存在的唯一标志。通常包含以下信息:
    秋招准备之——计算机操作系统_第2张图片
  • 程序段: 程序段是内被进程调度程序调度到CPU执行的程序代码段,可被多个进程共享
  • 数据段: 可以是进程对应的程序加工处理的原始数据,也可以是程序执行时产生的中间或最终结果。

5.进程的通信

进程通信指进程间的信息交换,高级通信方法分为三类:

  • 共享存储: 通信的进程之间存在一块可直接访问的共享空间,通过对这块空间进行读写操作实现进程之间的信息交换。
    秋招准备之——计算机操作系统_第3张图片
  • 消息传递: 消息传递系统中,进程间的数据交换是以格式化的消息为单位的,若通信间的进程不存在共享空间,则必须用消息传递的方式实现进程通信。通信方式包括直接通信和间接通信方式。
    在这里插入图片描述
  • 管道通信: 是消息传递的一种特殊方式。管道指用于连接一个读进程和一个写进程以实现他们之间通信的一个共享文件,又名pipe文件。发送方通过发送进程向管道中以字符流方式写管道,而接收方通过接收进程从管道中读数据。管道为半双工通信模式

6.线程的概念和多线程模型

  • 线程的概念: 线程是一个轻量级进程,是一个基本的CPU执行单元,也是程序执行流的最小单元。由线程ID、程序计数器、寄存器集合和堆栈组成。线程是进程中的实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,但可与同属一个进程的多个线程之间共享进程所拥有的全部资源。也有就绪、阻塞、运行三种状态。
  • 线程与进程的比较:
    • ①调度: 同一进程中,线程切换不会引起进程切换,而不同进程中的线程切换则会引起进程切换。
    • ②拥有资源: 进程是拥有资源的基本单位,而线程是独立调度的基本单位。进程不拥有系统资源,但可以访问隶属进程中的系统资源。
    • ③并发性: 进程可并发,线程也可并发,从而提高了系统的吞吐量
    • ④系统开销: 进程的切换开销大,同一进程中的线程切换开销很小
    • ⑤通信: 进程间的通信需要共享通信、消息传递来实现,而线程间的通信可直接通过读写进程数据段(如全局变量)来实现。
  • 线程的实现方式: 线程的实现分为两类:用户级线程内核级线程
    • 用户级线程: 线程的管理工作都由应用程序完成,内核意识不到线程的存在。通常,应用程序从单线程开始,然后通过调用线程库中的派生例创建一个在相同进程中运行的新线程。
    • 内核级线程: 线程的管理工作由内核完成,只为用户提供调度接口。
      秋招准备之——计算机操作系统_第4张图片

7. 多线程模型

  • 多对一模型: 多个用户级线程映射到一个内核级线程
    • 优点:线程管理在用户空间进行,效率高
    • 缺点:一个线程被阻塞时,整个进程都被阻塞;多个线程不能并行运行在多核处理机上
  • 一对多模型: 每个用户线程映射搭配一个内核级线程上
    • 优点:一个线程阻塞后,进程不会被阻塞,并发能力较强
    • 缺点:创建开销大,影响程序性能
  • 多对多模型: 既有多对一,也有一对多,克服了上述两种模型的缺点。

2.2 处理机调度

1.调度的概念

  • 调度: 从就绪队列中,按照一定的算法选择一个进程并将处理机分配给它运行,以实现进程并发执行。

  • 三级调度:

    • ①作业调度: 内存与辅存之间的调度,每个作业只调入一次,调出一次。主要任务是按一定的原则从外存上处于后备状态的作业中挑选一个或多个作业,给他们分配内存、输入/输出设备等资源,并建立相应的进程,以使他们获得竞争处理机的权利。作业调度执行频率较低。
    • ②中级调度: 又称内存调度。为了提高内存利用率和系统吞吐量引入。将那些暂时不能运行的进程,调至外存等待使其挂起。当他们具备运行条件且有空闲时,由中级调度决定将他们重新调入内存使其就绪。调度频率次高。
    • ③进程调度: 按照某种方法和策略从就绪队列中选取一个进程,将处理机分配给他,在系统中的调用频率很高。
      秋招准备之——计算机操作系统_第5张图片

2.调度的时机

可以调度的时机:

  • ①发生引起调度条件,且当前进程无法继续运行下去时,可马上进行调度与切换
  • ②中断处理或自陷处理结束后,返回被中断进程的用户态程序执行现场前,若请求调度,则可马上调度。

不可调度的情况:

  • ①中断过程中
  • ②进程在操作系统内核程序临界区中
  • ③需要完全屏蔽中断的原子操作中

3.调度的方式

  • 非剥夺调度方式: 非抢占式,当一个进程正在处理机上执行,即使有更紧迫的进程进入就绪队列,仍然让当前进程执行。实现简单,但无法用于分时系统和大多数实时系统
  • 剥夺调度方式: 抢占式

4.调度的基本准则

选择调度算法时的评价准则有以下几种:

  • CPU利用率: 尽可能不让CPU空闲

  • 系统吞吐量: 表示单位时间内CPU完成作业的数量。长作业会导致吞吐量降低。

  • 周转时间: 指从作业提交到作业完成所经历的是时间,包括作业等待、在就绪队列中排队,在处理机上运行,以及输入、输出操作所花费的时间总和。

    几种周转时间的计算公式:
    秋招准备之——计算机操作系统_第6张图片

  • 等待时间: 作业在就绪队列中等待的时间。处理机调度算法并不影响作业执行输入、输出的时间,只影响等待时间,故衡量调度算法通常仅需要考虑等待时间。

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

5.典型的调度算法

  • ①先来先服务(FCFS)调度算法: 同时适用于作业调度和进程调度,其调度原则都是选择最先进入队列的作业或进程。属于不可剥夺算法

    • 优点: 简单,适用于CPU繁忙型的调度
    • 缺点: 若长作业先到达系统,会使后面的短作业等待很长时间,不适用I/O繁忙型的调度。
  • ②短作业优先(SJF)调度算法: 适用于作业调度和进程调度。基本原则是,从后备队列中选择一个或多个估计运行时间最短的作业(进程)调度使用。

    • 优点: 能有效提高FCFS算法的调度时间和平均调度时间
    • 缺点: ①对长作业不利,可能导致长作业长期不被调度;②不能保证紧迫性作业优先处理(非剥夺算法)③运行时间只是估计的,有可能做不到短作业优先调度
  • ③优先级调度算法: 适用于作业调度和进程调度。基本原则是每次从后备作业中,选择优先级最高的作业进行调度。

    按照更高优先级能否抢占正在执行的进程,可将该算法分为:

    • 非剥夺式优先级调度算法
    • 剥夺式优先调度算法

    按照进程创建后优先级是否可以改变,可将该算法分为:

    • 静态优先级
    • 动态优先级
  • ④高响应比优先调度算法: 主要用于作业调度。是对FCFS和SJF调度算法的一种综合平衡,同时考虑每个作业等待时间和估计运行时间,每次作业调度时,先计算后备作业队列中每个作业的响应比,从中选出响应比最高的作业投入运行。响应比计算公式:
    在这里插入图片描述
    特点:

    • 作业等待时间相同,要求服务时间越短,响应比越高,有利于短作业
    • 要求服务时间相同时,等待时间越长,响应比越高,因此先来先服务
    • 长作业,响应比可随着等待时间的增加而提高,当足够高的时候,也能获得处理机,客服了饥饿状态,兼顾了长作业。
  • ⑤时间片轮转调度算法: 主要适用于分时系统,系统将所有就绪进程按到达时间的先后次序排成一个队列,进程调度程度总是选择就绪队列中的第一个进程执行,即先来先服务的原则,但仅能运行一个时间片。使用完一个时间片后,即使进程未完成运行,也必须释放出处理机给下一个就绪的进程,而自己则返回到就绪队列的队尾重新排队等候再次运行。

    该算法性能主要影响因素为时间片大小,时间片大小的决定因素通常有:系统响应时间、就绪队列中的进程数目和系统的处理能力。

  • ⑥多级反馈队列调节算法: 是时间片轮转调度算法和优先级调度算法的综合和发展。特点如下:

    • 设置多个就绪队列,并对各队列赋予不同的优先级,第一级最高,然后优先级递减
    • 赋予各个队列中进程执行时间片的大小也各不相同,优先级越高的队列中,时间片越小。
    • 当一个新进程进入内存后,先把其放入第1级队列的末尾,按照FCFS原则等待调度,当轮到该进程执行时,如果能在该时间片内完成,则可准备撤离系统。如果未完成,调度程序将其转入第二级队列的末尾,继续上述的方案。
    • 仅当第1级队列为空时,调度程序才调度第2级队列中的进程运行。如果处理机正在处理第i级队列中的进程,又有新进程进入优先级较高的队列,则此时新进程将抢占正在运行进程的处理机。

    优势为:

    • 终端型作业用户:短作业优先
    • 短批处理作业用户:周转时间较短
    • 长批处理作业用户:经过前面几个队列得到部分执行,不会长时间得不到执行。

2.3 进程同步

1.基本概念

  • ①临界资源: 虽然多个进程可以共享系统内的资源,但有些资源只能为一个进程所用,将一次仅允许一个进程使用的资源称为临界资源。对临界资源的访问,必须互斥地进行。访问临界资源的代码称为临界区。临界资源的访问过程分为四个部分:
    • 进入区: 在进入去要检查是否可进入临界区,如果可进入,则设置正在访问临界区的标志,以组织其他进程同时进入。
    • 临界区: 访问临界资源的代码
    • 退出区: 将正在访问临界区的标志清除
    • 剩余区: 代码中的剩余部分
  • ②同步: 也称直接制约关系,指为完成某种任务而建立的两个或多个进程,因为需要在某些位置上协调他们的工作次序而等待。
  • ③互斥: 也称间接制约关系,当一个进程进入临界区使用临界资源时,另一个进程必须要等待,当占用临界资源的进程退出后,另一个进程才能去访问临界资源。

2.实现临界区互斥的基本方法

  • 软件实现方式:

    • ①单标志法: 设置一个变量,用于指示被允许进入临界区的进程编号。缺点是两个进程必须交替进入,如果某个进程不再进入临界区了,那另一个也将无法进入。违背“空闲让进”原则

    • ②双标志法先检查: 设置一个数组flag,第i个进程,如flag[i]为false,则表示未进入临界区。缺点是可能会导致多个进程同时进入临界区,违背”忙则等待“原则

    • ③双标志法后检查: 先设置自己标志为True后,再检测对方状态,如果对方状态为True,则等待,否则进入临界区。缺点是,两个进程几乎同时想进入临界区时,很容易相互谦让,造成饥饿。

    • ④Peterson’s 算法: 为防止两个进程为进入临界区无限期等待的状况发生,又设置变量turn,每个进程在先设置自己标志后再设置turn标志,这时再同时检测另一个进程状态标志和不允许进入标志。这样可以保证当两个进程同时要求进入临界区,只允许一个进入。
      秋招准备之——计算机操作系统_第7张图片
      理解: pi进程,一旦设置flag[i]=true,则pj不能进入。如果pj已经进入临界区,则flag[j]=true,pi就不能进入。同时,饥饿现象也被避免了,因为如果pi被阻塞,表示flag[i]=true&&turn=j,这样pj不会被阻塞。

  • 硬件实现方式:

    • ①中断屏蔽法: 因为CPU只在中断发生时引起进程切换,屏蔽一切中断的发生,就能保证当前运行进程将临界区代码顺利执行完,从而保证了互斥的正确实现。

    • ②硬件指令方法:

      • TestAndSet指令: 该指令的功能是读出指定标志后,把该标志设置为真。
        秋招准备之——计算机操作系统_第8张图片
        这样就可以给每个临界资源设置一个共享变量lock,true表示资源正在被占用。在进程访问临界资源之前,利用该指令检查和修改标志lock,若有进程在临界区,则重复检查,直到进程退出,过程如下:
        秋招准备之——计算机操作系统_第9张图片
      • Swap指令: 该指令的功能是交换两个字的内容。
        秋招准备之——计算机操作系统_第10张图片
        给每个临界资源设置一个共享布尔变量lock,true表示资源正在占用,初值为false。在每个进程中再设置一个局部变量key,用于和lock交换信息。在进入临界区之前,先利用Swap指令交换lock和key的内容。然后检查key的状态,在进入临界区时,重复交换和检查过程,直到进程退出。过程如下所示:
        秋招准备之——计算机操作系统_第11张图片

3.信号量

信号量可用来解决互斥与同步的问题,只能被两个标准的原语wait(P操作)和signal(V操作)来访问。有以下几种类型:

  • ①整型信号量: 定义为一个用于表示资源数目的整数S,wait和signal操作可以表示为:
    秋招准备之——计算机操作系统_第12张图片
    整型信号量知道S<=0,就会一直测试,让进城处于”忙等“的状态。

  • ②记录型信号量: 除了需要一个用于代表资源数目的整数value外,在增加一个进程链表L,用于链接所有等待该资源的进程。wait操作可表示为:
    秋招准备之——计算机操作系统_第13张图片
    上述代码中,value表示资源数量。当value<0时,表示资源已经分配完了,没可用资源,因此进程调用block原语,进行自我阻塞,放弃处理机,并插入到资源等待队列L中。
    signal操作表示为:秋招准备之——计算机操作系统_第14张图片
    value<0时,表示归还资源后,等待队列中还有阻塞的进程,故调用weakup原语唤醒L中第一个等待唤醒的进程。

利用信号量,可以实现互斥和同步以及前驱关系:

  • ①利用信号量实现同步: 如下面的例子所示,设S为实现进程P1、P2同步的公共信号量,初始值为0,进程P2中的语句y要使用进程P1中语句x的运行结果,所以只有当语句x执行完成后语句y才能执行。
    秋招准备之——计算机操作系统_第15张图片
  • ②利用信号量实现进程互斥: 如下面的例子所示,设S为实现进程P1,P2互斥的信号量,由于每次只允许一个进程进入临界区,所以S的初始值应该为1,然后在访问临界区的时候,先进行P操作,这样就能防止其他进程访问。访问结束后,进行V操作,归还资源,以供其他进程访问资源。
    秋招准备之——计算机操作系统_第16张图片
  • ③利用信号量实现前驱关系: 可以通过利用信号量实现同步的思想,设置多个信号量,来实现程序之间的前驱关系。

4.管程

  • ①定义: 管程是由一组数据以及定义在这组数据之上的对这组数据的操作组成的软件模块,这组操作能初始化并改变管程中的数据和同步进程。在功能上和信号量及PV操作类似,属于一种进程同步互斥工具。管程内有一种条件变量的数据结构,只有在管程内中才能访问,对管程内的所以过程是全局的,只能通过waitsignal两个原语来操作。
  • ②组成:
    • 1) 局部用于管程的共享数据结构说明
    • 2)对该数据结构进行操作的一组过程
    • 3)对局部于管程的共享数据设置初始化值的语句
  • ③基本特征:
    • 1)局部于管程的数据只能被局部于管程内的过程所访问
    • 2)一个进程只有通过调用管程内的过程才能进入管程访问共享数据
    • 3)每次仅允许一个进程在管程内执行某个内部过程

5.经典同步问题

  • 生产者-消费者问题: 需要设置三个信号量:互斥信号量mutex,初始值为1;满信号量full,初始值为0;空信号量empty,初始值为n。具体操作如下:
    秋招准备之——计算机操作系统_第17张图片

  • ②读者-写者问题: 有读者和写者两组并发进程,共享一个文件,当两个或以上的读进程同时访问共享数据时不会产生问题,但如果某个写进程和其他进程(读进程和写进程)同时访问共享数据时则可能导致数据不一致。要求:①允许多个读者可以同时对文件执行读操作;②只允许一个写者往文件中写信息;③任一写者在完成写操作之前,不允许其他读者或写者工作;④写者执行写操作前,应让已有的读者和写者全部退出

    第一种写法:

    上面的写法是读优先的,容易导致写进程饿死,因此有了下一种写法:

  • ③哲学家进餐问题: 如下图,一张桌子上坐着5个哲学家,每两个哲学家之间摆一根筷子,每个哲学家面前有一碗米饭。哲学家饿了时,试图拿筷子,只有拿到两根筷子,才能进餐。为了防止死锁或饥饿现象,有两种解决方案:①让他们同时拿两个筷子;②对每个哲学家的工作制定规则,避免饥饿或死锁发生。
    秋招准备之——计算机操作系统_第18张图片
    解决方法: 定义一个互斥信号量数组chopstick[5]={1,1,1,1,1},用于5个筷子的互斥访问。对哲学家按照0~4编号,哲学家i左边的筷子为i,右边的筷子为(i+1)%5
    秋招准备之——计算机操作系统_第19张图片
    当五个哲学家都要进餐,分别拿了左边的筷子时(其实不需要5个,只要相邻的两个哲学家,同时拿了左边的筷子),就拿不到右边的筷子了,这样就出现了死锁。

    为了解决此问题,规定只有一个哲学家左右两边的筷子都可用时,才允许他抓起筷子
    在这里插入图片描述
    秋招准备之——计算机操作系统_第20张图片

  • ④吸烟者问题: 有三个抽烟者,一个供应者。每个抽烟者不停卷烟并抽烟,抽烟的原材料有:烟草、纸、胶水。三个抽烟者分别拥有三种材料中的一种。供应者每次随机地将两种材料放到桌上,这时拥有剩余材料的抽烟者就卷烟并抽烟。

    解决方法: 设置offer1offer2offer3三个信号量分别表示烟草和纸、烟草和胶水、胶水和纸组合,信号量finish用于互斥地进行抽烟动作。
    秋招准备之——计算机操作系统_第21张图片

2.4 死锁

1.概念

  • 定义: 多个进程因竞争资源而造成的互相等待,若无外力作用,这些进程都无法向前推进。
  • ②产生原因:
    • 1)系统资源的竞争:因为竞争不可剥夺的资源产生
    • 2)进程推进顺序非法:因为进程请求和释放资源的顺序不当,本质是资源的等待
  • ③死锁产生的必要条件:
    • 互斥条件: 进程要求对资源进行排他性控制
    • 不剥夺条件: 进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,只能由持有进程主动释放
    • 请求和保持条件: 进程已经保持了至少一种资源,但又提出新的资源请求,而该资源已被其他进程占有,但对自己保持的资源不放
    • 循环等待条件: 存在一种进程循环等待链,链中每一个进程已获得的资源同时被下一个进程所请求。

2.死锁的处理策略

  • ①预防死锁:资源分配前,设置某些限制条件,破坏产生死锁的四个必要条件中的一个或几个

    • 1)破坏互斥条件:允许系统中的资源都能共享,基本不可行
    • 2)破坏不剥夺条件:若进程请求新的资源而得不到满足时,必须释放已持有的资源。实现复杂,会造成前一阶段的工作实效。常用于状态易于保存和恢复的资源。
    • 3)破坏请求和保持条件:采用预先静态分配方法,即进程在运行前一次申请完它所需要的全部资源,在它的资源未满足前,不投入使用。一旦投入运行,资源就一直归他所有,不再提出资源请求。实现简单,但会导致资源严重浪费,且容易造成饥饿现象。
    • 4)破坏循环等待条件:可采用顺序资源分配法。首先给系统中的资源编号,规定每个进程,必须按编号递增的顺序请求资源,同类资源一次申请完。此方法容易限制新资源的增加,也会给用户编程带来麻烦。
  • ②避免死锁:资源分配过程中,用某种方法防止系统进入不安全状态,从而避免死锁

    • 系统安全状态: 在系统进行资源分配之前,先计算此次资源分配的安全性,若此次分配不会导致系统进入不安全状态,则将资源分匹配给进程,否则让进程等待。
    • 银行家算法: 基本思想是:将操作系统看成银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于想银行家贷款。申请资源时,若资源充足,则分配资源,否则推迟分配资源。
  • ③检测死锁并解除: 通过系统的检测及时检测出死锁的发生,然后采取某种措施解除死锁(通常需要剥夺资源)。

    • 资源分配图: 用资源分配图来描述资源分配过程,图中用圆圈代表进程,框代表一类资源,从进程到资源的有向边叫请求边,表示进程申请一个单位的该类资源;从资源到进程的边叫分配边,表示该类资源已经有一个资源被分配给了该进程。
      秋招准备之——计算机操作系统_第22张图片

    • 死锁定理: 通过资源分配图来检测是否存在死锁,过程为:

      • ①在资源分配图中,找出既不阻塞又不是孤立点的进程Pi(==即找到有一条有向边与进程结点相连,且该有向边对应资源的申请数量小于等于系统中已有空闲资源数量),消去它所要的请求边和分配边,使之成为孤立节点。

      • ②进程Pi所释放的资源,可以唤醒某些因为等待这些资源而阻塞的进程,原来阻塞的景进程可以变成非阻塞状态。如下图,P2就可以变成非阻塞。

      • ③不断执行上述两步,若能消去所有边,则该资源分配图就是可简化的。出现死锁的添加是资源分配图不可简化,该条件称为死锁定理
        秋招准备之——计算机操作系统_第23张图片
        发现死锁后,可通过采取措施解除死锁:

        • 1)资源剥夺法: 挂起某些死锁进程,并抢占他的资源,将这些资源分配给其他的死锁进程。其中,应防止被挂起的资源的饥饿
        • 2)撤销进程: 强制撤销部分,甚至全部死锁进程并剥夺这些进程的资源。撤销原则可以按照进程优先级和撤销进程代价的高低进行。

3.银行家算法(参考博客)

  • ①涉及的数据结构:

    • 1)可利用资源向量Avaliable: 这是一个含有 m 个元素的数组,其中的每一个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态地改变。如果 Available[j] = K,则表示系统中现Rj类资源K个。

    • 2)最大需求矩阵Max: 这是一个n * m的矩阵,它定义了系统中n个进程中的每个进程对m类资源的最大需求。如果Max[i,j] = K,则表示进程i需要Rj 类资源的最大数目为K。

    • 3)分配矩阵 Allocation: 这也是一个n * m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果 Allocation[i,jl = K,则表示进程i当前己分得Rj类资源的数目为K。

    • 4)需求矩阵Need: 这也是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j] = K,则表示进程i还需要Rj类资源K个方能完成其任务。

      三个矩阵的关系为:
      Need[i,j]=Max[i,j]-Allocation[i,j]

  • ②算法描述

    设Requesti为进程Pi的请求矢量,如果Requestii=K,表示进程Pi需要j类资源K个。发出资源请求后,系统按照如下步骤检查:

    • 1)如果 Requesti[j] ≤ Need[i,j]便转向步骤2);否则认为出错,因为它所需要的资源数已超过它所宣布的最大值。

    • 2)如果 Requesti[j] ≤ Available[j],便转向步骤3);否则,表示尚无足够资源,Pi须等待。

    • 3)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值

      Available[j] = Available[j] - Requesti[j];
      Allocation[i,j] = Allocation[i,j] + Requesti[j];
      Need[i,j] = Need[i,j] - Requesti[j]

    • 4)系统执行安全性算法,检查此次资源分配后系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。

  • ③安全算法:

    • (1) 设置两个向量:①工作向量Work,它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work = Available② Finish,它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做 Finish[i] = false;当有足够资源分配给进程时,再令Finish[i] = true。

    • (2) 从进程集合中找到一个能满足下述条件的进程

      • ① Finish[i] = false;
      • ② Need[i,j] ≤ Work[j];

      若找到,执行步骤(3),否则,执行步骤(4)。

    • (3)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
          Work[j] = Work[j] + Allocation[i,j];
          Finish[i] = true;
          go to step 2;

    • (4)如果所有进程的 Finish[i] =true都满足,则表示系统处于安全状态;否则,系统处于不安全状态。

三、内存管理

3.1 内存管理概念

1.内存管理的概念

  • 概念: 操作系统对内存的划分和动态分配
  • 功能:
    • 内存空间的分配与回收
    • 地址转换:逻辑地址与物理地址之间的相互转换
    • 内存空间扩充:利用虚拟存储技术或自动覆盖技术,从逻辑上扩充内存
    • 内存保护:保证各作业在各自的存储空间内运行,互不干扰

2.进程运行的基本原理和要求

进程运行的一些基础知识:

  • ①程序装入和连接: 将程序和数据装入内存,将用户源程序变成可在内存中执行的程序,需要以下步骤:

    • 1)编译

    • 2)链接: 将编译后的模块以及所需要的库函数链接在一起,形成一个完成的装入模块。链接分为静态链接和动态链接:

      • 静态链接:程序运行前,将目标模块和他们所需的库函数链接成一个完整的可执行程序,以后不再拆开
      • 装入时动态链接:装入内存时,采用边装入边链接的链接方式
      • 运行时动态链接:在程序执行中需要目标模块时,才对它进行链接
    • 3)装入: 由装入程序装入模块装入内存运行。分为绝对装入和可重定位装入:

      • 绝对装入:编译时,如果知道程序将驻留在内存的某个位置,编译时将产生绝对地址目标代码。装入时,按照装入模块中的地址将程序和数据装入内存。由于程序中的逻辑地址和实际内存地址完全相同,故不需要对程序和数据的地址修改。仅适用于单道程序。
      • 可重定位装入:装入时,需要根据相对地址,重新定位。在一个作业装入内存时,必须分配其要求的全部内存空间。
      • 动态运行装入:装入程序在把装入模块装入内存后,并不立即把装入模块中的相对地址转换为绝对地址,而是把这种转换推迟到程序真正要执行的时候才进行,装入内存的所有地址均为相对地址,这种方式需要一个重定位寄存器的支持。其可将程序分配到不连续的存储区中,在运行时,根据需要动态分配内存
  • ②逻辑地址空间与物理地址空间:编译后,每个目标模块都是从0号单元开始编址,称为该目标模块的相对地址。系统会进行相对地址到绝对地址的映射和转换。

  • ③内存保护: 内存分配前,需要保护操作系统不受用户进程的影响,同时保护用户进程不受其他用户进程的影响。可采用两种方法:

    • 1)在CPU中设置一对上下限寄存器,存放用户作业在主存中的下限和上限地址,每当CPU要访问一个地址时,分别和两个寄存器的值比较,判断有无越界
    • 2)通过采用重定位寄存器(或基址寄存器)和界地址寄存器(限长寄存器)来实现,重定位寄存器包含最小的物理地址,而界地址寄存器包含逻辑地址的最大值。CPU访问地址时,和这两个地址核对,保证操作系统和其他用户程序及数据不被该进程的运行影响。

3.覆盖与交换

覆盖和交换是在多道程序环境下用来扩充内存的两种方法

  • 覆盖: 基本思想是将用户控件分成一个固定区和若干个覆盖区,将经常活跃的部分放在固定区,其余部分按调用关系分段。首先将那些即将访问的段放入覆盖区,其他段放在外存中,在需要调用前,系统再将其调入覆盖区,替换原有的段。用于同一个程序或进程中
  • 交换: 基本思想是把处于等待状态(或在CPU调度原则下被剥夺运行权利)的程序从内存引动入辅存,把内存空间腾出来,然后把准备好竞争CPU运行的程序从辅存移到内存。用于不同进程或作业之间进行

4.连续内存分配技术

指给用户分配一个连续的内存空间,包括单一连续分配、固定分区分配和动态分区分配

  • 单一连续分配: 内存在此方式下分为系统区和用户区,系统去仅仅给操作系统使用。这种方式无需内存保护,因为内存中永远只有一道程序,不会发生越界。

  • 固定分区分配: 将用户内存空间划分为若干个固定大小的区域,每个分区只能装入一道作业。当有分区空闲时,便可以再从外存的后备作业队列中,选择适当大小的作业装入该分区。该方式在划分分区时,有分区大小相等和大小不等两种情况。

    存在的问题:①可能程序太大不能放入任何分区,需要使用覆盖技术来使用内存空间;②主存利用率小,当程序小于分区大小时,也占了一个完整的分区空间,形成内部碎片,造成空间浪费。

  • 动态分区分配: 这种方法不预先划分内存,而是在进程装入内存时,根据进程的大小动态地创建分区,并使分区的大小正好适合进程的需要。动态内存分配会导致内存中出现外部碎片,这种问题可以通过紧凑技术来解决

    • 动态内存的分配策略
      • ①首次适应:空闲分区以地址递增的次序链接。分配内存时顺序查找,找到第一个能满足要求的空闲分区(效果最好
      • ②最佳适应:空闲分区按容量递增形成分区链,分配时,找到第一个能满足容量要求的空闲分区
      • ③最坏适应:又称最大适应,空闲分区以容量递减的次序链接,分配时,找到第一个满足要求的最大分区
      • ④邻近适应:由首次适应算法演变而来,不同之处是分配内存时从上次查找结束的位置开始继续查找。

5.非连续分配管理方式

该方式允许将一个程序分散地装入到不相邻的内存分区中。根据分区的大小是否固定,分为分页存储管理方式和分段存储管理方式。

  • (1)基本分页存储管理方式——有利于提高内存利用率

    • ①分页的基本思想:将内存划分为大小相等且固定的块,块相对较小,作为主存的基本单位。每个进程也以块为单位进行划分,进程在执行时,以块为单位逐个申请主存中的块空间。

    • ②分页存储的基本概念:

      • 1)页面和页面大小:进程中的块称为,内存中的块称为页框,外存中也以同样方法划分,称为。进程在执行时,需要申请主存空间,就是要为每个页分配页框。为方便转换,页面大小应是2的整数幂。同时页面大小应该适中。

      • 2)地址结构:分页存储管理的逻辑地址结构如下所示:
        在这里插入图片描述
        逻辑地址包含两部分第一个是页号,第二个是页内偏移量,表示相对P页开始的位置。逻辑地址长度为32位,0-11位为页内地址,即每页大小为4KB;12-31位为页号,地址空间最多允许有220

      • 3)页表:为了便于在内存中找到进程的每个页面所对应的物理块,系统为每个进程建立了一张页表,记录页面在内存中对应的物理块号。页表一般放在内存中,作用是实现从页号到物理块号间的地址映射
        秋招准备之——计算机操作系统_第24张图片

    • ③基本地址变换机构

      地址变换结构的任务是将逻辑地址转换为内存中的物理地址,变换借助页表实现。
      秋招准备之——计算机操作系统_第25张图片
      设页面大小为L,逻辑地址A到物理地址E的变换过程如下,

      • 1)计算页号P(P=A/L)和页内偏移量W(W=A%L)
      • 2)比较页号P和页表长度M,若P>=M,则产生越界中断,否则继续
      • 3)页表中页号P对应的页表项地址=页表起始地址F+页号P×页表项长度,取出该页表项内容b,即为物理块号。
      • 4)计算E=b×L+W,用得到的物理地址E去访问内存
    • ④具有块表的地址变换机构

      若页表全部放在内存中,则存取一个数据或一条指令至少要访问内存两次(一次度页表数据,另一次根据地址读内存),速度较慢。故在地址变换机构中,增设一个具有并行查找能力的高速缓冲器——快表又称联想寄存器,以加速查找过程。
      秋招准备之——计算机操作系统_第26张图片
      在有快表的地址变换结构中,地址变换过程为:

      • 1)先去快表中查找相应页号
      • 2)如果能查到,直接取出该页对应的块号,与页内偏移量拼接形成物理地址。
      • 3)如果查不到,则去访问主存中的页表,读出页表后,会同时将其存入快表,以便下次继续使用
    • ⑤两级页表

      如果使用一级页表,页表占用的空间会非常大,故采用页表映射的思想,使用层次结构的页表,建立上一级页表,用于存储页表的映射关系。进程执行时,只需要将第一级页表调入内存,根据第一级页表找到找到第二级页表号,再根据第二级页表号去映射物理地址。
      秋招准备之——计算机操作系统_第27张图片

  • (2)基本分段存储管理方式——有利于反映程序的逻辑结构并有利于段的共享

    • ①分段: 段式管理方式按照用户进程中的自然段划分逻辑空间。例如,用户进程由主程序、两个子程序、栈和一段数据组成,就可以把这个用户进程划分为5个段,每段从0开始编址,并分配一段连续的地址空间(段内连续,段间可不连续)。逻辑地址由段号S和段内偏移量W两部分组成。
      秋招准备之——计算机操作系统_第28张图片
    • ②段表: 每个进程都有一张逻辑空间与内存空间映射的段表,每个短表项对应进程的一个段,短表项记录该段在内存中的起始地址和段的长度,用于实现逻辑段到物理内存区的映射内容如下:
      秋招准备之——计算机操作系统_第29张图片
      映射过程如下:
      秋招准备之——计算机操作系统_第30张图片
    • ③地址变换机构: 实现进程从逻辑地址到物理地址的变换功能,变换过程如下所示:
      秋招准备之——计算机操作系统_第31张图片
    • ④段的共享与保护: 分段系统中,段的共享是通过两个作业的段表中相应表项指向被共享的段的同一物理副本来实现的。此时,在共享时,必须注意互斥问题
  • (3)段页式管理方式

    将页式管理方式和段式管理方式结合起来,形成段页式存储管理方式。在该系统中,作业的地址空间首先被分为若干个逻辑段,然后再将每一段分为若干个大小固定的页。而对于内存的管理,仍使用页式管理
    秋招准备之——计算机操作系统_第32张图片
    此时,作业的逻辑地址就分为三个部分:
    在这里插入图片描述
    地址变换过程如下:
    秋招准备之——计算机操作系统_第33张图片

3.2 虚拟内存管理

1.虚拟内存的基本概念

  • (1)传统内存管理方式的不足:

    • ①一次性:作业必须一次性全部装入内存后,才能开始运行。会导致大作业不能装入内存运行;大量作业由于内存不足无法,只能少数作业先运行。
    • ②驻留性:作业被装入内存后,就一直驻留在内存,其任何部分都不会被换出,直到作业结束。
  • (2)局部性原理

    • ①时间局部性: 程序中的某条指令、访问过的某些数据,不久后可能再次被访问
    • ②空间局部性: 一旦程序访问了某个存储单元,不久后,附近的存储单元也可能被访问。
  • (3)虚拟存储器的定义和特征

    • 定义: 基于局部性原理,程序接入时,可以将程序的一部分装入内存,而其余部分留在外存,就可以启动程序执行。在程序执行过程中,当所访问的信息不存在时,由操作系统将所需要的部分调入内存,然后继续执行程序。另一方面,操作系统将内存中暂时不使用的内容换出到外存。这样,好像为用户提供了一个比实际内存大得多的存储器,称为虚拟存储器。虚拟内存技术实际就是建立了内存——外存的两级存储器结构,利用局部性原理实现高速缓存
    • 特征:
      • 1)多次性:无需一次将作业一次装入内存,而是允许多次装入
      • 2)对换性:作业运行时,无需一直常驻内存,允许在作业运行过程中,进行换进和换出
      • 3)虚拟性
  • (4)虚拟内存技术的实现

    虚拟内存的实现需要建立在离散分配的内存管理方式的基础上。有三种实现方式:

    • ①请求分页存储管理
    • ②请求分段存储管理
    • ③请求段页式存储管理

2.请求分页管理方式

请求分页系统,在基础分页系统的基础上,增加了请求调页功能也页面置换功能。在该系统中,只要将当前需要的一部分页面装入内存,便可启动作业运行。在作业执行过程中,当所要访问的页面不在内存时,再通过调页功能将其调入,同时还可以利用置换功能将暂时不同的页面换出到外存上,以腾出内存空间。需要以下机制的支持:

  • ①页表机制: 不同于基础分页管理系统,在请求页表项中新加了以下字段
    在这里插入图片描述

    • 状态位P:用于指示该页是否已经调入内存
    • 访问字段A:用于记录本页在一段时间内被访问的次数,或记录本页已有多长时间未被访问,供置换功能的参考
    • 修改位M:标记该页在调入内存后是否被修改过
    • 外存地址:该页在外存上的地质
  • ②断页中断机制: 在请求分页系统中,每当所要访问的页面不在内存时,便产生一个断页中断,请求操作系统将所需的页调入内存。此时应将缺页的进程堵塞(调页完成唤醒)

  • ③地址变换机构: 检索过程如下:
    秋招准备之——计算机操作系统_第34张图片

3.页面置换算法

好的页面置换算法要有较低的页面更换频率。常见的算法有:

  • ①最佳置换算法: 选择被淘汰的页面将是以后永远不使用的,或是最长时间内不再被访问的页面,这样可以保证最低的缺页率。但是由于无法知道哪些页面最长时间不再访问,故该算法无法实现。但该算法经常用来评价其他算法

  • ②先进先出页面置换算法: 优先淘汰最早进入内存的页面,亦即在内存中驻留时间最久的页面。该算法虽然实现简单,但有以下缺点:

    • 1)页面切换次数会很频繁,切换页面与实际运行规律不符
    • 2)如果对—个进程未分配它所要求的全部页面,有时就会出现分配的页面数增多但缺页率反而提高的异常现象(参考博客)。
  • ③最近最久未使用算法: 选择最近最长时间未访问过的页面予以淘汰。该算法性能较好。但是需要栈和寄存器的硬件支持,实现困难且开销大。

  • ④时钟置换算法: 时钟替换算法的具体规则如下(参考博客):

    • 当内存中无对应数据时访问位为0即可置换之后再变换访问位,访问位为1不置换仍然变换访问位(变成0)然后指针下移。当内存中有对应数据时,访问位变换(变成1),指针下移。
    • 每访问一次,无论是否发生置换,访问位都要变换(变成1)。

    可以在使用位的基础上,再增加一个修改位,得到改进型的CLOCK置换算法。此时,每一帧都处于下下面四种情况之一:
    秋招准备之——计算机操作系统_第35张图片
    算法的操作步骤如下(参考博客):

    • 从指针当前位置开始,扫描缓冲区。选择遇到的第一个帧(u=0,m=0)的帧用于替换,这个扫描过程中,对每个跳过的帧,将使用位设置成0
    • 如果第一步失败,则重新扫描,查找(u=0,m=1)的帧,选择遇到的第一个帧用于替换,在扫描过程中,将跳过的帧的使用位设置为0
    • 如果第二部失败,指针回到最初的位置,并且集合中所以帧的使用位均为0,重复第一步。

4.页面分配策略

  • 页面分配需要考虑的问题:

    • 分配给一个进程的页数越小,那同一时刻会有越多的进程在内存中,从而提高处理机的时间利用效率
    • 如果一个进程在内存中的页数过少,缺页导致的错误率会较高
    • 如果页数过多,给特定进程分配更多的主存空间对该进程的错误率没有明显的影响。
  • 基于上面的因素,通常采用以下三种页面分配策略

    • ①固定分配局部替换: 给每个进程分配固定的物理块,不够就在这些物理块中替换。这种策略,分配的物理块太少会频繁缺页,太多会使CPU和其他利用率下降
    • ②动态分配全局替换: 先给每个进程分配一定数量的物理块,操作系统也保持一定数量的空闲的物理块队列。当某进程发生缺页时,系统从空闲物理块队列中取出一个物理块分配给该进程,并将想要调入的页装进该块中。这种策略,会盲目地给进程增加物理块,会导致多道程序并发能力下降
    • ③动态分配局部替换: 先给每个进程分配一定数量的物理块,操作系统也保持一定数量的空闲的物理块队列。当缺页时,先从这些物理块中替换。当替换地特别频繁时,再从系统的空闲物理块中取出物理块分配给进程。
  • 调入页面的时机

    • ①预调页策略: 以预测为基础,将预计在不久之后会访问的页面预先调入内存。但成功率较低。
    • ②请求调页策略: 在运行中,需要访问的页面不在内存中而提出请求,由系统将所需的页面调入内存。

    一般情况下,两种策略都会使用。

5.抖动

  • 概念:刚刚换出的页面马上又要换入主存,刚刚换入的页面马上就要换出主存,这种频繁的页面调度行为称为抖动,或颠簸。如果一个进程的换页时间多于执行时间,那这个进程就在抖动。抖动的主要原因是某个进程频繁访问的页面数目高于可用的物理页帧数目

6.工作集

指的是在某段时间间隔内,进程要访问的页面集合。经常被使用的页面需要再工作集中,而长期不被使用的页面要从工作集中丢弃。为防止抖动的出现,要选择合适的工作集大小。

四、文件管理

4.1 文件系统基础

1.文件的概念:

  • 文件: 由创建者定义的一组相关信息的集合。

  • 文件的结构:

    • 无结构文件: 将数据按顺序组织成记录并积累保存,以字节为单位,常用于对基本信息单位操作不多的文件,如程序代码等。

    • 有结构文件: 按照记录的组织方式可以分为:
      1)顺序文件: 文件的记录一个一个地顺序排列

      2)索引文件: 利用索引表保存记录位置,查找时根据索引表查找以提高检索速度。索引表本身是定长记录的顺序文件

      3)索引顺序文件: 顺序和索引文件两种组合形成的。

      4)直接文件或散列文件: 通过散列值来定位物理地址的文件

2.目录

  • 目录的结构:
    • 单级目录结构
    • 两级目录结构
    • 多级目录结构
    • 无环图目录结构:减轻多级目录结构共享难的问题

4.2 文件系统的实现

1.文件系统层次结构

秋招准备之——计算机操作系统_第36张图片

2.目录实现

  • 线性列表: 每个目录都是一个线性表,创建新文件时,首先在线性表中搜索有没有同名文件,然后再再目标表后面增加一个目录项。优点是实现简单,但查找速度较慢。
  • 哈希表: 根据文件名通过哈希函数得到一个哈希值,然后根据这个值返回一个指向线性列表中的指针。优点是查找迅速,删除插入也比较简单,但冲突的避免比较难处理。

3.文件实现

  • 文件分配方式:

    • 连续分配:每个文件在磁盘上占用一组连续的块,磁盘地址定义了磁盘上的一个线性排列。优点是实现简单,存取速度快。缺点是文件长度不宜动态增加,一旦需要增加就要移动大量的盘块。
      秋招准备之——计算机操作系统_第37张图片

    • 链接分配: 链式分配,有隐式和显式两种方式。隐式方式类似于链表,优点是不会产生碎片,文件动态增长方便。缺点是,无法直接访问盘块,只能从头指针顺序访问文件。显式方式,在内存中有一个文件分配表,显式地存放对应块的下一块链接指针,即下一个块号。可以显著地提高检索速度,大大减少访问磁盘的次数。
      秋招准备之——计算机操作系统_第38张图片

    • 索引分配: 在链接分配的基础上,把每个文件所有的盘块号集中放在一起构成索引块(表)。为了解决索引块过大的问题,可以使用链接方案(多个索引块以链表的方式链接起来)、多层索引方案、混合索引方案(多种索引分配方式相结合)。
      秋招准备之——计算机操作系统_第39张图片

  • 文件存储空间管理: 文件存储设备分成许多大小相同的物理块,并以块交换信息,故文件存储空间管理,其实是对空闲块的组织和管理。有以下方法:

    • ①空闲表法: 属于连续分配方式,利用下面所示的空闲盘块表中的信息,使用首次适应法、循环首次适应法等来分配存储空间。
      秋招准备之——计算机操作系统_第40张图片

    • ②空闲链表法: 属于链接分配。有以下两种链表方式

      • 空闲盘块链:将所有空闲盘块链接在一起,然后每次去找个链表中找是否有足够的空间分配
      • 空闲盘区链:以盘区为单位,将所有盘区拉成一条链(一个盘区有多个盘块),每次以盘区为单位,在盘区内分配。
    • ③位示图法: 利用二进制的一位来表示磁盘中盘块的使用情况,每个盘块都有一个二进制位与之对应。0表示空闲,1表示占用。分配时,根据表中的信息来分配。
      秋招准备之——计算机操作系统_第41张图片

    • ④成组链接法(UNIX中使用): 上述方法不适用于文件太大的情况,成组链接法可以解决。这种方法结合了空闲表和空闲链表两种方法,大致思想是:把顺序的n个空闲扇区地址保 存在第一个空闲扇区内,其后一个空闲扇区内保存另一个顺序空闲扇区的地址,如此继续,直到所有的空闲扇区均予以链接。
      秋招准备之——计算机操作系统_第42张图片

4.3 磁盘组织与调度

1.磁盘结构

  • 磁盘盘面

    • 磁道:磁盘盘面上的一组同心圆,每个磁道和磁头等宽
    • 扇区:每个磁道划分为几百个扇区,每个扇区固定存储大小(512B),一个扇区称为一个盘块。扇区按固定圆心角划分,故磁盘的存储能力受限于最内道的最大记录密度。
  • 磁盘结构

    磁盘由磁头臂、用于旋转的主轴和用于数据输入输出的电子设备组成。所有盘面上相对位置相同的磁道组成柱面。磁盘地址用 “柱面号+盘面号+扇区号” 表示
    秋招准备之——计算机操作系统_第43张图片

2.磁盘调度算法

  • 磁盘读写操作的时间组成

    • 寻找时间Ts 活动头磁盘在读写信息前,将磁头移动到指定磁道所需要的时间。这个时间除跨越n条磁道的时间外,还包括启动磁臂的时间s,即:
      在这里插入图片描述

    • 延迟时间Tr 磁头定位到某一磁道的扇区所需要的时间,若磁盘的转速为r,则
      在这里插入图片描述

    • **传输时间Tt:**从磁盘读出或向磁盘写入数据所经历的时间,这个时间取决于每次所读/写的字节数b和磁盘的旋转速度r,若一个磁道上的字节数为N,那传输时间为:
      在这里插入图片描述
      总的平均存取时间为:
      在这里插入图片描述

  • 磁盘调度算法:

    • ①先来先服务: 根据进程请求访问磁盘的先后顺序进行调度。优点是实现简单,具有公平性。缺点是,随机调度时,会有很多次的磁磁头移动,会比较耗时。
    • ②最短寻找时间优先: 优先调度处理的磁道是与当前磁头所在磁道距离最近的磁道,以使每次的寻找时间最短。优点是比先来先服务有更好的性能,缺点是可能导致饥饿现象。
    • ③扫描算法(电梯算法):磁头当前移动方向上选择与当前磁头所在磁道距离最近的请求作为下一次服务的对象。实际上在最短寻找时间优先的基础上规定了磁头运动的方向。可避免饥饿现象,但是不利于远离磁头一端的请求。
    • ④循环扫描算法: 在扫描算法的基础上,规定磁头单向移动来提供服务,回返时直接快速移动到起始端而不服务任何请求。消除了扫描算法对两端请求不公平的现象。
      减小磁盘读写操作时间的方法:
    • 数据尽量放在同一磁道
    • 数据尽量放在同一柱面

你可能感兴趣的:(复习)