本文最后更新于 2025-03-07,文章超过7天没更新,应该是已完结了~

一、操作系统概述

1.1 操作系统的定义与目标

定义:操作系统是控制管理计算机系统的硬软件,分配调度资源的系统软件

目标:方便性,有效性(提高系统资源的利用率、提高系统的吞吐量),可扩充性,开放性。

1.2 操作系统的基本功能

  • 统一管理计算机资源:计算机的资源主要分为处理器资源、IO设备资源、存储器资源和文件资源等。操作系统的核心任务之一是将这些资源进行统一管理,确保各个程序都能合理、高效地使用资源。例如,通过调度算法管理处理器资源、利用驱动程序管理 IO 设备资源、分配内存管理存储器资源,确保资源不会出现冲突、浪费或死锁的情况。

  • 对计算机资源的抽象:为了让开发者不需要深入了解底层硬件细节,操作系统会对硬件资源进行抽象。比如,通过 IO 设备管理软件提供统一的读写接口,开发者可以使用相同的接口操作不同的 IO 设备;文件管理软件则提供文件操作接口,开发者可以通过这些接口创建、删除、修改文件,而无需关注底层的存储管理。这种抽象极大简化了程序开发,让程序员专注于应用逻辑。

  • 提供用户与计算机之间的接口:操作系统为用户和程序提供了一些标准的交互方式,包括图形用户界面(GUI)、命令行接口(CLI)以及系统调用接口。图形用户界面让用户通过图标和菜单直接操作系统资源,命令行接口则提供了更灵活和快速的资源操作方式,而系统调用接口为应用程序访问底层资源提供标准化的途径。这些接口是用户和程序与操作系统通信的桥梁,简化了用户对计算机资源的使用体验。

1.3 操作系统的特征

最基本的特征,互为存在条件:并发,共享;

(1)并行:指两个或多个事件可以在同一个时刻发生,多核CPU可以实现并行,一个cpu同一时刻只有一个程序在运行;

(2)并发:指两个或多个事件可以在同一个时间间隔发生,用户看起来是每个程序都在运行,实际上是每个程序都交替执行。

(3)共享性:操作系统的中资源可供多个并发的程序共同使用,这种形式称之为资源共享。

  • 互斥共享:当资源被程序占用时,其它想使用的程序只能等待。

  • 同时访问:某种资源并发的被多个程序访问。

虚拟和异步特性前提是具有并发性。

(4)虚拟性: 通过时分和空分复用技术,把有限的物理资源转化为多个逻辑资源,为每个应用程序提供“专属”资源的假象。

  • 时分复用:通过将资源按时间分片的方式为多个程序交替分配。比如,处理器资源在多道程序中按照一定的时间片轮流分配给不同的程序,达到“同时”运行多个程序的效果。这种方式称为“分时系统”,大幅提升了资源利用率,使得多个程序可以“并发”地享有计算机的处理能力。

  • 空分复用:通过将空间划分来虚拟化物理资源,比如内存和磁盘。对于磁盘空间,操作系统把物理磁盘划分为逻辑分区(如C盘、D盘),每个分区在逻辑上独立,方便用户管理数据和安装程序;对于内存资源,操作系统利用“虚拟内存”技术让程序在逻辑上拥有更大的内存空间,即便物理内存有限。这种技术既方便了编程,也提升了资源利用率。

通过这些虚拟化技术,操作系统可以在有限的资源上支持更多的应用程序同时运行,让每个应用程序在逻辑上享有“独立”的资源。

(5)异步性:多道程序环境中,操作系统允许多个进程并发执行,但由于资源竞争或外部条件的变化,各进程的执行会有不确定性,表现出“停停走走”的运行特征。

  • 异步性表现在进程的执行受限于可用资源和调度策略,因此不能保证一旦开始执行就会连续执行到结束。例如,在多道程序环境中,某个进程可能会因为等待输入输出操作(如磁盘读取)而暂时停止执行,当资源空闲或操作完成后再恢复执行。

  • 由于资源竞争或调度机制,进程的运行状态(执行、等待、暂停等)在时间上并不确定,因而在宏观上看,进程是“断断续续”地运行。

这种“异步”特性确保了多道程序可以高效利用计算资源,使系统在资源不足时仍然能够支持多个任务的交替执行,从而提高了系统的吞吐量和响应性。

1.4 操作系统的中断处理

中断机制的作用:为了在多道批处理系统中让用户进行交互;

中断产生:

  • 进入管态(特权态):当发生中断时,CPU立即切换到管态(或称特权态、系统态、核心态)。这是因为中断处理涉及对硬件和系统资源的控制操作,这些操作只能在特权态下进行,以保障系统安全和资源的稳定管理。

  • 暂停当前进程:中断发生时,当前正在运行的进程会被暂停,CPU保存该进程的状态(如程序计数器PC、寄存器内容等),以便在中断处理结束后能够恢复并继续执行被中断的进程。这个过程通常叫“上下文切换”,目的是确保在中断处理期间,不会丢失当前进程的运行信息。

  • 进入中断处理程序:操作系统内核负责识别和处理中断。不同的中断信号(如键盘输入、网络数据包到达、定时器溢出等)会触发不同的中断处理程序。例如,键盘输入中断触发时会调用键盘中断处理程序,而定时器中断触发时则会调用定时器中断处理程序。这些程序由内核提供并严格受控,确保系统的稳定性和安全性。

  • 中断处理的优先级:系统通常会根据中断类型设置优先级。例如,电源故障或硬件故障中断通常有更高优先级,需立即处理;而某些软件中断优先级相对较低。通过这种优先级控制,CPU能够及时处理最关键的任务。

  • 恢复并继续执行:当中断处理程序完成后,CPU会恢复被中断进程的状态(即加载保存的寄存器内容和程序计数器等),并切回用户态(普通用户程序的运行模式),使得被中断的进程从暂停位置继续运行。通过这种方式,中断处理能够高效地响应外部事件,而不会影响当前任务的连续执行。

中断的分类:

在计算机系统中,中断分为 内中断外中断,它们的区别主要在于信号来源和触发条件:

  1. 内中断(也称异常、例外或陷入)

  • 信号来源:内中断的信号来自 CPU内部,与正在执行的指令直接相关。

  • 触发原因:通常由程序执行过程中出现的异常情况或错误触发,例如:

  • 除零错误:当一个指令试图除以零时触发。

  • 非法指令:当CPU遇到不支持或无效的指令时触发。

  • 访问越界:当程序尝试访问不允许的内存区域时触发(如访问未分配的内存)。

  • 系统调用:程序通过特定指令主动触发内中断,以请求操作系统的服务。

  • 处理方式:内中断通常会触发内核的异常处理程序,内核会评估是否需要终止、恢复或重新执行当前指令。

  • 特点:内中断在指令执行过程中主动或被动触发,其目的主要是确保系统的安全性和稳定性。

  1. 外中断

  • 信号来源:外中断的信号来自 CPU外部,与当前指令的执行无直接关系。

  • 触发原因:外中断通常由外部硬件设备发出,例如:

  • 定时器中断:操作系统使用定时器中断来执行时间片调度,确保多个程序公平地分享CPU资源。

  • 输入输出中断:当输入设备(如键盘、鼠标)或输出设备(如打印机、显示器)需要CPU处理数据时发出。

  • 硬件故障:硬件错误或故障也可能触发外中断,例如电源故障、硬盘错误等。

  • 处理方式:外中断会让CPU暂停当前指令,进入相应的中断服务程序处理该事件。处理完毕后,CPU恢复原任务继续执行。

  • 特点:外中断的触发与当前执行指令无关,是系统响应外部事件和硬件请求的重要机制。

总结:

  • 内中断 主要由CPU内部或程序本身的异常触发,用于处理执行指令时的错误或特殊请求(如系统调用)。

  • 外中断 由外部设备或硬件发出信号触发,用于让CPU响应外部事件和硬件请求。

外中断的处理过程:

  1. 每执行完一个指令后,CPU都需要检查当前是否有外部中断 信号;

  2. 如果检查到外部中断信号,则需要保护被中断进程的CPU环境(如程序状态字PSW,程序计数器PC、各种通用寄存器)把他们存储在PCB(进程控制块中);

  3. 根据中断信号类型转入相应的中断处理程序;

  4. 恢复原进程的CPU环境并退出中断,返回原进程继续执行。

二、进程管理

2.1 进程管理之进程实体

为什么需要进程:

进程是系统进行资源分配和调度的基本单位;

进程作为程序独立运行的载体保障程序正常执行;

进程的存在使得操作系统资源的利用率大幅提升。

进程控制块(PCB):

用于描述和控制进程运行的通用数据结构,记录进程当前状态和控制进程运行的全部信息,是进程存在的唯一标识。

进程(Process)与线程(Thread):

线程:操作系统进行**运行调度的最小单位**。

进程:系统进行**资源分配和调度的基本单位**。

区别与联系:

  • 一个进程可以有一个或多个线程;

  • 线程包含在进程之中,是进程中实际运行工作的单位;

  • 进程的线程共享进程资源;

  • 一个进程可以并发多个线程,每个线程执行不同的任务。

2.2 进程管理之五状态模型

1. 就绪状态

  • 描述:此时进程已具备除CPU以外的所有资源(如进程控制块、内存、栈空间、堆空间等),并等待CPU的分配。

  • 转换条件:当CPU空闲时,操作系统的调度程序会选择一个就绪进程,将其从就绪队列中移出并分配CPU资源,转变为执行状态。

2. 执行状态

  • 描述:进程在获得CPU后进入执行状态,此时其程序正在CPU上运行。

  • 转换条件

  • 当进程执行完成或遇到需要等待的资源(如IO操作)时,可能会切换到阻塞状态。

  • 如果时间片耗尽但仍有后续任务,会返回到就绪状态。

3. 阻塞状态

  • 描述:进程因等待某些资源(如等待输入输出完成)或条件满足(如等待某个信号)而暂停执行,暂时放弃CPU。

  • 转换条件:当所需资源或条件满足后,阻塞的进程重新进入就绪状态,等待下一次获得CPU的机会。

4. 创建状态

  • 描述:在进程创建的初始阶段,操作系统为其分配进程控制块(PCB)和部分初始资源,但进程所需的所有资源还未完全准备就绪。

  • 转换条件:当资源准备完成后,创建状态的进程会进入就绪状态,等待调度获得CPU。

5. 终止状态

  • 描述:进程执行结束或被终止后进入终止状态,此时系统负责清理该进程的资源并回收PCB。

  • 转换条件:在所有资源回收完成后,进程的控制块将被移出内存,进程生命周期完全结束。

2.3 进程管理之进程同步

生产者-消费者问题:有一群生产者进程在生产产品,并将这些产品提供给消费者进程进行消费,生产者进程和消费者进程可以并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程需要将所生产的产品放到缓冲区中(+1操作),消费者进程可以从缓冲区取走产品消费(-1操作)。

产生问题:当两者并发执行时可能出差错,导致预期的结果与真实的结果不相符:当执行生产者+1和消费者-1操作之后,缓冲区的值从10变为了11。

哲学家进餐问题:有5个哲学家,他们的生活方式是交替的思考和进餐,哲学家们共同使用一张圆桌,分别坐在5张椅子上,圆桌上有5只碗和5只筷子。平时哲学家们只进行思考,饥饿时则试图取靠近他们的左右两只筷子,只有两只筷子都被拿到的时候才能进餐,否则等待,进餐完毕后,放下左右筷子进行思考。

这会导致以下的问题,筷子就相当于临界资源:

临界资源指的是一些虽作为共享资源却又无法同时被多个线程共同访问的共享资源。当有进程在使用临界资源时,其他进程必须依据操作系统的同步机制等待占用进程释放该共享资源才可重新竞争使用共享资源。

进程同步的作用:对竞争资源在多进程间进行使用次序的协调,使得并发执行的多个进程之间可以有效使用资源和相互合作。

进程间同步的四原则:

  • 空闲让进:当资源处于空闲状态时,允许其他进程使用它。这是一种资源的主动管理策略,避免资源在空闲时不被利用,提升系统资源的利用率。

  • 忙则等待:如果资源正被其他进程使用,新的请求进程就必须等待,直到资源释放。这种机制防止资源冲突,即确保在任一时刻仅有一个进程在使用资源,维护了资源的互斥性。

  • 有限等待:系统会保证在有限时间内,等待资源的进程能够获得资源。这一原则避免了无限期等待问题,也称为“饥饿”问题,确保所有等待资源的进程都有机会获得资源,从而提高系统公平性。

  • 让权等待:当进程在等待资源时,它需要主动让出CPU,让其他进程执行。这种机制允许CPU资源被有效地利用,而不是被等待中的进程占用着,从而提高整体系统效率。

2.3.1进程同步的实现方法(重要)

fork 系统调用

  • 功能fork 是操作系统提供的用于创建进程的系统调用,它可以创建一个与父进程几乎相同的子进程。

  • 返回值fork 返回两次,一次给父进程(返回子进程的 PID),一次给子进程(返回 0)。这使得父进程可以判断哪个是子进程。

  • 新进程的特点

  • 子进程继承父进程的内存空间、文件描述符等,但拥有自己独立的资源,如 PCB(进程控制块)。

  • 子进程与父进程共享同样的代码段,但有独立的数据段堆栈段。这样,父子进程虽然起始状态一样,但可以独立执行不同的任务。

理解关键fork 是 Unix/Linux 系统中创建并发任务的基础,确保新进程能在不干扰父进程的情况下独立运行。

1.共享内存

  • 作用:共享内存是一种快速的数据传递方式,它在进程间创建一个可以同时访问的内存区域。

  • 隔离与共享:操作系统默认情况下将每个进程的内存空间独立起来(内存隔离),避免一个进程访问或修改其他进程的数据。但是,共享内存突破了这种限制,使得多个进程可以访问相同的物理内存片段,以便快速交换数据。

  • 同步需求:虽然共享内存能够快速传递数据,但没有提供内置的同步机制,需要使用信号量或互斥锁等机制来协调访问,防止数据竞争问题。

理解关键:共享内存能够极大地提高数据共享效率,但需要额外的同步措施来确保数据一致性。适合需要频繁、快速传递大量数据的场景。

2.Unix 域套接字

  • 作用:Unix 域套接字是一种高级的进程间通信(IPC)方法,适用于同一台计算机上的进程之间的数据传输。

  • 套接字的类比:尽管“套接字”一词最常用于网络通信,但 Unix 域套接字也适合本地进程通信,提供与网络套接字类似的接口和功能。

  • 应用场景:比如 NginxuWSGI 等应用使用 Unix 域套接字在同一台机器上与其他服务交互,因为其效率高,且可以省去网络传输的开销。

理解关键:Unix 域套接字是一种面向本地通信的高效套接字,应用广泛、易于操作,适合服务器端应用之间的高速通信。

2.3.2 线程同步的方法(重要)

1、互斥锁:

  • 定义:互斥锁是一种用于保护共享资源的同步机制,确保在任何时刻只有一个线程可以访问该资源。

  • 状态:互斥锁有两种状态:锁定(加锁)和解锁。一个线程在访问共享资源之前加锁,完成后解锁。

  • 特点

  • 原子性:通过加锁和解锁,确保操作的原子性,避免数据竞争。

  • 适用场景:适用于需要保护临界区的多线程程序,特别是资源访问较少的情况。

2、自旋锁:

  • 定义:自旋锁是一种轻量级的锁,适用于短时间的锁持有情况。

  • 特点

  • 线程在尝试获取自旋锁时,如果锁被占用,就会在一个循环中持续检查(自旋),而不会释放CPU。

  • 效率:在多核CPU上,自旋锁效率较高,因为避免了线程上下文切换的开销。

  • 缺点:在单核CPU上,自旋锁会导致忙等待,浪费CPU时间,不适合长时间锁定的情况。

3、读写锁:

  • 定义:读写锁是一种允许多个读操作并发执行的同步机制,但对写操作是互斥的。

  • 特点

  • 适合读多写少的场景,允许多个线程同时读取共享资源,提高读性能。

  • 当有线程进行写操作时,所有其他线程(读或写)都会被阻塞,确保写操作的独占性。

4、条件变量:

  • 定义:条件变量是一种用于线程间同步的机制,允许线程在满足某些条件时被唤醒。

  • 特点

  • 线程可以在条件变量上等待,直到另一个线程发出信号,表明某个条件已满足。

  • 常与互斥锁结合使用,确保在检查条件时对共享资源的独占访问。

  • 适用于生产者-消费者模型等需要线程等待某个条件的场景。

2.4 Linux的进程管理

进程类型

  1. 前台进程(Foreground Process)

  • 定义:前台进程是指与用户直接交互的进程。它通常在终端中运行,用户可以看到其输出并与之交互。

  • 特点

  • 具有终端输入输出。

  • 用户可以通过键盘直接与进程进行交互。

  • 当前台进程运行时,用户无法进行其他操作。

  1. 后台进程(Background Process)

  • 定义:后台进程是在后台运行,不与终端直接交互的进程。

  • 特点

  • 优先级通常低于前台进程。

  • 可以通过在命令后添加“&”符号启动。

  • 用户可以继续在终端执行其他命令,而后台进程会在后台运行。

  1. 守护进程(Daemon Process)

  • 定义:守护进程是一种特殊的后台进程,在系统启动时启动,并在系统关闭时终止。

  • 特点

  • 通常不与用户交互,提供系统服务(如网络服务、调度任务等)。

  • 名称通常以“d”结尾,如 crond(任务调度守护进程)、sshd(SSH守护进程)、httpd(HTTP守护进程)、mysqld(MySQL守护进程)。

  • 守护进程通常会在特定事件发生时被唤醒或定期执行。

进程标记

  1. 进程ID(PID)

  • 定义:进程ID是一个非负整数,用于唯一标识系统中的每个进程。

  • 特点

  • 每个进程在系统中有一个唯一的PID,进程之间的PID不能重复。

  • PID通常用于进程管理和调试。

  1. 进程状态标记

  • 状态标记是用来描述进程当前状态的符号:

  • R:表示进程处于运行状态(Running),即正在CPU上执行。

  • S:表示进程处于睡眠状态(Sleeping),即等待某些事件(如I/O操作完成)。

  • D:表示进程处于不可中断的睡眠状态(Uninterruptible Sleep),通常是等待I/O操作。

  • Z:表示僵尸状态(Zombie),即进程已结束但其父进程尚未收集其状态信息。

  • T:表示进程被停止(Stopped),可能是由于接收到信号。

操作Linux进程的相关命令:

ps命令:列出当前的进程,结合-aux可以打印进程的详细信息(ps -aux);

top命令:查看所有进程的状态;

kill命令:给进程发送信号。

三、作业管理

3.1 作业管理之进程调度

定义:指计算机通过决策决定哪个就绪进程可以获得CPU使用权。

什么时候需要进程调度?

1. 主动放弃调度

  • 进程正常终止

  • 当一个进程完成其任务并正常终止时,操作系统需要调度,以便为其他就绪进程分配CPU时间。

  • 运行过程中发生异常而终止

  • 如果进程在运行时遇到错误或异常(如除零错误、非法内存访问等),操作系统需要处理这些异常并重新调度其他可执行的进程。

  • 主动阻塞

  • 当进程因某种原因(如等待I/O操作完成、请求资源等)主动放弃CPU时,操作系统需要调度其他就绪进程,以充分利用CPU资源。

2. 被动放弃调度

  • 时间片用完

  • 在采用时间片轮转调度策略的系统中,每个进程分配一个固定的时间片,当时间片用完后,操作系统会进行调度,选择下一个就绪的进程执行。

  • 有更高优先级的进程进入就绪队列

  • 如果一个高优先级的进程进入就绪队列,操作系统需要抢占当前运行的低优先级进程,调度高优先级进程执行。

  • 有更紧急的事情需要处理

  • 当I/O中断或其他外部事件发生时,操作系统需要中断当前进程的执行,以处理这些更紧急的事件,然后再恢复之前的进程。

进程调度方式:

非抢占式调度:只能由当前运行的进程主动放弃CPU;

处理器一旦分配给某个进程,就让该进程一直使用下去;调度程序不以任何原因抢占正在被使用的处理器。

抢占式调度:可由操作系统剥夺当前进程的CPU使用权。

允许调度程序以一定的策略暂停当前运行的进程;保存好旧进程的上下文信息,分配处理器给新进程。

进程调度的三大机制:

就绪队列的排队机制:为了提高进程调度的效率,将就绪进程按照一定的方式排成队列,以便调度程序可以最快找到就绪进程。

选择运行进程的委派机制:调度程序以一定的策略,选择就绪进程,将CPU资源分配给它。

新老进程的上下文切换机制:保存当前进程的上下文信息,装入被委派执行进程的运行上下文。

进程调度算法:

1. 先来先服务(FCFS, First-Come, First-Served)算法

  • 原理:按照进程到达就绪队列的顺序进行调度,先到的进程优先获得CPU。

  • 优点

  • 简单易实现,易于理解。

  • 对于批处理系统,较长的进程可以得到完整的执行时间。

  • 缺点

  • 存在“饥饿”现象:如果后面有短进程不断加入,长进程可能长时间得不到执行。

  • 可能导致较大的平均等待时间,尤其是在短作业频繁插入的情况下。

2. 短进程优先(SJF, Shortest Job First)调度算法

  • 原理:优先调度估计运行时间最短的进程。调度器选择就绪队列中运行时间最短的进程执行。

  • 优点

  • 可实现较低的平均等待时间和周转时间。

  • 对短进程特别友好,能够快速完成小任务。

  • 缺点

  • 可能导致长作业进程饥饿,特别是在短作业频繁出现时。

  • 对于需要准确预测运行时间的系统较难实现,预测不准确可能导致调度效率降低。

3. 高优先权优先(Priority Scheduling)调度算法

  • 原理:每个进程被赋予一个优先级,调度器优先选择优先级高的进程执行。

  • 优点

  • 紧急任务能快速得到处理,提高了响应性。

  • 可用于实时系统,确保重要任务得到优先执行。

  • 缺点

  • 可能导致低优先级进程饥饿,特别是在高优先级进程持续出现的情况下。

  • 需要有效的机制来管理优先级的分配和调整,以避免饿死现象。

4. 时间片轮转(Round Robin, RR)调度算法

  • 原理:按照FIFO的原则排列就绪进程,每个进程被分配一个固定的时间片,时间片到期后进程被挂起并放入队列尾部。

  • 优点

  • 相对公平,所有进程都有机会执行,适合多用户环境。

  • 提高了系统对交互式进程的响应性。

  • 缺点

  • 时间片过短会增加上下文切换的开销,影响性能。

  • 时间片过长可能导致响应性下降,特别是对实时任务。

总结

这四种调度算法各有优缺点,适用场景也不同。在实际应用中,操作系统通常结合多种算法,以便在公平性、响应性和吞吐量之间找到最佳平衡。选择合适的调度策略可以显著提高系统的效率和用户体验。

3.2 作业管理之死锁

3.2.1 进程死锁、饥饿、死循环的区别:

死锁:两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。永远在互相等待的进程称为死锁进程。竞争资源(共享资源数量不满足各进程需求)、进程调度顺序不当,当调度顺序为A->B->C->D时会产生死锁,但改为A->D->B->C则不会产生。

饥饿:由于长期得不到资源导致进程无法推进;

死循环:代码逻辑BUG。

死锁的四个必要条件:

1. 互斥条件
  • 定义:互斥条件意味着某个资源在同一时间只能被一个进程使用。如果一个进程正在使用某个资源,其他进程必须等待,直到该资源被释放。

  • 影响:当多个进程需要互斥访问同一资源时,如果进程A占用了资源R1,进程B也想访问R1,进程B将被迫等待,这可能为死锁的发生提供条件。

2. 请求保持条件
  • 定义:进程在保持已获得资源的同时,提出对新资源的请求。如果请求的资源当前被其他进程占用,进程将被阻塞,而已经持有的资源不被释放。

  • 影响:这种条件使得进程在请求新资源时不释放已占用的资源,从而导致其他进程可能陷入等待,进而形成死锁的机会。

3. 不可剥夺条件
  • 定义:已经分配给某个进程的资源在进程完成之前不能被剥夺。即使操作系统需要这些资源,也不能强制收回。

  • 影响:这一条件使得即使某个进程因为请求新资源而被阻塞,它持有的资源也不会被释放,从而导致其他进程无法获得所需的资源,形成死锁。

4. 环路等待条件
  • 定义:在发生死锁的情况下,必然存在一个进程-资源的环形链,即进程A等待资源B,进程B等待资源C,...,最终进程Z又等待资源A,从而形成环路。

  • 影响:虽然环路等待本身并不一定导致死锁,但如果存在环路等待且满足其他条件,则死锁必然会发生。

死锁的处理策略:

1、预防死锁的方法:

破坏四个必要条件的中一个或多个

  1. 破坏互斥条件:将临界资源改造成共享资源(Spooling池化技术);(可行性不高,很多时候无法破坏互斥条件)

  2. 破坏请求保持条件:系统规定进程运行之前,一次性申请所有需要的资源;(资源利用率低,可能导致别的线程饥饿)

  3. 破坏不可剥夺条件:当一个进程请求新的资源得不到满足时,必须释放占有的资源;(实现复杂,剥夺资源可能导致部分工作失效,反复申请和释放造成额外的系统开销)

  4. 破坏环路等待条件:可用资源线性排序,申请必须按照需要递增申请;(进程实际使用资源顺序和编号顺序不同,会导致资源浪费)

虽然这些方法各有优缺点,且在实际应用中可能面临不同的挑战,但理解这些方法的核心思想对于设计出更为有效的死锁预防和处理策略是非常重要的。实际中,往往需要结合多种策略以找到平衡点,确保系统资源的有效利用和进程的顺畅执行。

2、银行家算法:

检查当前资源剩余是否可以满足某个进程的最大需求;如果可以,就把该进程加入安全序列,等待进程允许完成,回收所有资源;重复1,2,直到当前没有线程等待资源;

3、死锁的检测和解除:

死锁检测算法,资源剥夺法,撤销进程法(终止进程法),进程回退法;

四、存储管理

存储管理为了确保计算机有足够的内存处理数据;确保程序可以从可用内存中获取一部分内存使用;确保程序可以归还使用后的内存以供其他程序使用。

4.1 存储管理之内存分配与回收

内存分配的过程:单一连续分配(已经过时)、固定分区分配、动态分区分配(根据实际需要,动态的分配内存)。

动态分区分配算法:

  • 首次适应算法:分配内存时,从开始顺序查找适合内存区,若无合适内存区,则分配失败,每次从头部开始,使得头部地址空间不断被划分;

  • 最佳适应算法:要求空闲区链表按照容量大小排序,遍历以找到最佳适合的空闲区(会留下越来越多的内部碎片)。

  • 快速适应算法:要求有多个空闲区链表,每个空闲区链表存储一种容量的空闲区。

ps:

  • 内部碎片:指在分配内存时,分配的内存块比实际需要的内存大,未使用的部分造成的浪费。例如,如果一个进程需要 50KB 内存,但分配了 64KB,那么 14KB 就是内部碎片。

  • 外部碎片:指系统中存在许多小的空闲内存区域(碎片),但总的空闲内存足够大,无法满足一个大的内存请求。这种情况通常发生在频繁的内存分配和释放后,尤其是在内存较小的情况下。

内存回收的过程:

  • 回收区在空闲区下方:不需要新建空闲链表节点;只需要把空闲区1的容量增大即可;

  • 回收区在空闲区上方:将回收区与空闲区合并;新的空闲区使用回收区的地址;

  • 回收区在空闲区中间方:将空闲区1、空闲区2和回收区合并;新的空闲区使用空闲区1的地址;

  • 仅仅剩余回收区:为回收区创建新的空闲节点;插入到相应的空闲区链表中去;

4.2 存储管理之段页式存储管理

页式存储管理:将进程逻辑空间等分成若干大小的页面,相应的把物理内存空间分成与页面大小的物理块,以页面为单位把进程空间装进物理内存中分散的物理块。

页面大小应该适中,过大难以分配,过小内存碎片过多;页面大小通常是512B~8K;

现代计算机系统中,可以支持非常大的逻辑地址空间(232~264),具有32位逻辑地址空间的分页系统,规定页面大小为4KB,则在每个进程页表中的页表项可达1M(2个20)个,如果每个页表项占用1Byte,故每个进程仅仅页表就要占用1MB的内存空间。

段式存储管理:将进程逻辑空间分成若干段(不等分),段的长度由连续逻辑的长度决定, 逻辑上划分程序,通常包括代码段、数据段、栈段等 。

段页式存储管理:现将逻辑空间按照段式管理分成若干段,再将内存空间按照页式管理分成若干页,分页可以有效提高内存利用率,分段可以更好的满足用户需求。

4.3 存储管理之虚拟内存

虚拟内存(Virtual Memory)是一种内存管理技术,它使得程序可以使用比物理内存更大的地址空间。虚拟内存的基本思想是将部分不常用的数据或代码从物理内存转移到磁盘上,从而腾出内存空间给当前正在使用的进程。以下是对虚拟内存的详细解释,包括其工作原理、优点和缺点。

虚拟内存的基本概念

  • 虚拟地址空间:每个进程都有自己的虚拟地址空间,这个地址空间可以大于实际可用的物理内存。操作系统将这些虚拟地址映射到物理内存和磁盘上的空间。

  • 页面(Page):虚拟内存通常以固定大小的页面为单位进行管理。常见的页面大小有4KB或8KB。

工作原理

  1. 页面调度

  • 当进程需要访问一个虚拟地址时,操作系统会首先检查这个地址是否在物理内存中。如果在,称为“命中”(Page Hit);如果不在,则称为“缺页”(Page Fault)。

  1. 缺页处理

  • 当发生缺页时,操作系统会将所需的页面从磁盘加载到物理内存。这一过程通常涉及以下步骤:

  • 选择页面:操作系统可能需要选择一部分现有的物理内存页面进行替换。选择的策略可以是“最近最少使用”(LRU)、“先进先出”(FIFO)等。

  • 写回磁盘:如果被替换的页面已经修改过,操作系统需要将其写回磁盘。

  • 加载页面:将需要的页面从磁盘加载到物理内存中的空闲位置。

  • 更新页表:更新页表以反映新的页面到物理内存的映射。

  1. 映射机制

  • 操作系统使用页表(Page Table)来维护虚拟地址到物理地址的映射。每个进程都有自己的页表,当访问虚拟地址时,操作系统通过页表找到对应的物理地址。

优点

  • 扩展内存容量:虚拟内存允许程序使用比物理内存更大的地址空间,适合大型应用程序。

  • 内存保护:每个进程有独立的虚拟地址空间,防止进程之间互相干扰,提高系统稳定性。

  • 有效利用内存:只将当前正在使用的数据保留在物理内存中,而将不常用的数据移到磁盘,从而减少物理内存的需求。

缺点

  • 性能开销:频繁的缺页可能导致性能下降,因为访问磁盘比访问内存慢得多。这个现象被称为“缺页中断”或“抖动”(Thrashing)。

  • 复杂性:实现虚拟内存需要操作系统的复杂管理,包括维护页表和处理缺页异常。

总结

是操作系统内存管理的关键技术,使得多道程序运行和大程序运行成为现实,把程序使用内存划分,将部分暂时不使用的内存放置在辅存,实际是对物理内存的扩充

4.4 Linux的存储管理

Buddy 内存管理算法

1. 概述 Buddy 内存管理算法是一种高效的内存分配和管理方法,旨在减少内存碎片,尤其是外部碎片。它的基本思想是将内存块分为一对一对的“伙伴”,每个内存块的大小是2的幂次方。通过这种结构,内存的分配和回收变得相对简单和高效。

2. 工作原理

  • 分配:当一个进程请求内存时,算法会查找最小的适合块。如果没有合适的块,算法会向上寻找更大的块,并将其一分为二,形成两个“伙伴”,直到找到合适的块为止。此时,分配的内存块将被标记为已用。

  • 回收:当内存块被释放后,算法会检查其“伙伴”是否也为空闲。如果是,两个伙伴会合并为一个更大的块,从而减少内存的外部碎片。

3. 优势

  • 效率高:由于内存块的大小是2的幂次方,计算和管理非常简单。

  • 减少碎片:通过伙伴合并的策略,能够有效减少外部碎片。

4. 劣势

  • 内部碎片:由于内存块是2的幂次方,可能导致一些内存的浪费(内部碎片)。

  • 并发访问问题:在多线程环境下,可能需要额外的锁机制来管理并发访问。

Linux 交换空间

1. 概述 交换空间(Swap)是Linux操作系统中用于虚拟内存的一部分,它允许系统在物理内存不足时,将不常用的数据或进程移动到磁盘以释放内存空间。

2. 工作原理

  • 交换机制:当物理内存满时,Linux会将一些内存页面(pages)转移到交换空间,以腾出更多的内存给当前运行的进程。这一过程称为页面置换(paging out)。

  • 交换空间的配置:在系统初始化时,用户可以指定交换空间的大小和位置。交换空间通常是一个分区,也可以是一个文件。

3. 交换空间的作用

  • 提供额外的内存:允许系统在物理内存不足时继续运行,避免崩溃或错误。

  • 提高系统稳定性:通过管理内存资源,使系统能够运行更多的进程,即使物理内存有限。

4. 性能考虑

  • 性能下降:由于磁盘的访问速度远低于内存,因此过多地依赖交换空间可能会导致系统性能显著下降。系统在进行页面置换时可能会变得缓慢,尤其是在频繁交换的情况下(称为“交换抖动”)。

  • 合理配置:为了优化性能,合理配置物理内存和交换空间的大小非常重要。一般建议交换空间的大小为物理内存的1到2倍,但具体情况应根据实际应用需求而定。

总结

Buddy 内存管理算法通过将内存块分为2的幂次方和伙伴合并的方式,有效减少了内存外碎片,并提高了内存管理效率。Linux 的交换空间机制则为系统提供了额外的内存资源,使得即使在物理内存不足时,系统依然可以保持稳定运行。然而,过多依赖交换空间会影响系统性能,因此合理的内存和交换空间管理是非常重要的。