操作系统结构
知识点范围://老师划的重点和可能考的知识点,背过就有95+分,这些全看明白 再看我的另一篇博客→三年真题答案和考前老师出的习题
全都看会至少95+
--------关个注呗 点个赞呗--------
操作系统的定义?(对下管理,对上服务)
操作系统是一组控制和管理计算机硬件和软件资源、合理地对各类作业进行调 度,以及方便用户的程序集合。
操作系统是用户和计算机的接口,同时也是计算机硬件和其他软件的接口。
中断与陷阱
1.2.1 *中断 换成 CPU 的话需要如何处理中断呢? (1) 保护断点:即保存下一将要执行的指令的地址,就是把这个地址送入堆栈。 (2) 寻找中断入口:根据不同的中断源所产生的中断向量,查找不同的入口地 址,入口地址处存放着中断处理程序。 (3) 执行中断处理程序。 (4) 中断返回:执行完中断指令后,就从中断处返回到主程序,继续执行。
1.2.2 陷阱 陷阱是一种软件产生的中断,源于程序出错(如除 0 或访问内存无效)或者源于 用户程序的特别请求(系统调用 system call),完成中断处理后将 CPU 控制权再交给提出陷阱请求的程序。
1.2.3 *中断(interrupt)与陷阱(trap)的区别 陷阱又被称作软中断,与(硬)中断相比,软中断是软件实现的中断,也就是程 序运行时其它程序对它的中断;而硬中断是硬件实现的中断,是程序运行时设备对它的中断。(硬中断是由外部事件引起的,因此具有随机性和突发性;而软中断的发生不是随机的,而是由程序安排好的)
**双重模式操作(Dual-Mode Operation)
双重模式操作(Dual-Mode Operation)
组成:用户模式(user mode)和内核模式(kernel mode),即用户模式下应用程序需要操作系统的服务时必须切换至核心模式由操作系统完成相应请求。
动机:将能引起机器损害的机器指令作为特权指令(privilegedinstruction),如转换到用户模式,IO 控制,定时器管理和中断管理等,通过识别模式位保证特权指令只能由操作系统完成,保护操作系统和用户程序不受错误用户程序影响。
系统模式(内核模式、特权状态、系统态、管态):操作系统管理程序运行时的状态,较高的特权级别。 当 CPU 处于系统模式时,程序可以执行特权指令,访问所有资源,并可以改变处理器状态。
用户模式(用户态、目态、常态):用户程序运行时的状态,较低的特权级别。当 CPU 处于用户状态时,程序只能执行非特权指令。
CPU 状态转换: 目态 → 管态:通过中断(系统调用、中断事件)。 管态 → 目态:设置 PSW(修改程序状态字)。
**系统调用(system call)
系统调用(system call) 用户请求 OS 执行含有特权指令的任务 操作系统内核提供一系列预定功能,通过一组称为系统调用的接口呈现给编程人 员,系统调用把应用程序的请求传给内核,系统调用相应的内核函数完成所需的处理,将处理结果返回给应用程序。C 或 C++编写。系统调用是内核的一部分。
系统调用(内核函数)运行于核心态;而普通的函数调用由函数库或用户自己提供,运行于用户态。
如何找到相应的内核函数? 实际上每一个系统调用都和一个数相关联,通过索引表找到相应的内核函数,类似于中断向量表,系统调用本质上也是一种软中断(trap)。
使用 API 而不使用系统调用的原因 如果说系统调用是内核和应用程序信息交流的通道,那么 API 就是程序和开发人 员之间交流的通道,它为开发人员掩盖系统调用的细节,提供访问并操作硬件的权利。 原因:API 的可移植性强;系统调用操作难度较大(细节和困难)
向操作系统传递参数的三种方法 (1) 通过寄存器来传递参数 (2) 将参数存在内存的块和表中,将块的地址通过寄存器来传递 (3) 参数通过程序压入堆栈,通过操作系统弹出
系统调用大致分为五大类:进程控制,文件管理,设备管理,信息维护和通信
策略与机制
策略 (Policy)
策略指的是系统应该做什么,也就是决策的制定。例如:
-
进程调度策略:决定哪个进程应该在某个时刻被执行。
-
内存分配策略:决定如何分配内存给进程。
策略是关于选择的高层次决策,它们回答的是“做什么”的问题。
机制 (Mechanism)
机制指的是如何实现这些策略的具体方法和过程。例如:
-
进程切换机制:具体实现进程切换的方法,如保存和恢复进程上下文。
-
内存管理机制:具体实现内存分配和释放的方法,如分页和分段。
机制是低层次的实现细节,它们回答的是“怎么做”的问题。
简洁理解
-
策略是“做什么”的问题。
-
机制是“如何做”的问题。
操作系统四种结构以及优缺点
-
操作系统的四种结构及其优缺点
-
模块结构(重点)
特点:整个系统按功能进行设计和模块划分。系统是一个单一的、庞大的的软件系统。每一个模块之间使用接口进行通讯,必要的时候可以将一部分的内容加载到内核中进行操作。
它类似于层次结构,但是模块之间没有上下层的依赖关系,模块之间可以相互调用,更加灵活;它类似于微核,但是必要时候会将内容加载到内核中,比微核更有效率。
优点:具有一定灵活性,模块之间转接的灵活性使运行中的高效率;结构紧密,接口简单直接;
缺点:功能划分和模块接口难保正确和合理;模块之间的依赖关系(功能调用关系)复杂(调用深度和方向)。
-
分层结构
-
特点:操作系统分成多个层次,每层只调用下层功能。
-
优点:结构清晰,易于维护,低层错误不影响高层。
-
缺点:层间调用多,效率低。
-
-
微内核结构(客户-服务器结构):(重点)
-
特点:将所有非基本部分从内核中移走,并将它们实现为系统程序或用户程序,从而得到更小的内核。仅核心功能在内核,其余服务在用户态。
用户程序和系统服务(运行在用户空间)通过微内核以消息传递形式进行通信,并不会直接交互
-
优点:可靠性高,易扩展和修改,操作系统容易移植
-
缺点:性能较低,通信开销大。(由于系统功能总开销的增加而导致系统性能的下降(各个服务之间缺少通信,只能依靠微核的信息传递,导致效率下降。)
-
-
虚拟机结构
-
特点:通过虚拟化技术创建多个虚拟机。
-
优点:安全性高,虚拟机独立,便于开发。
-
缺点:性能开销大。
-
进程管理
----进程管理----
**进程概念以及进程状态图
*进程 简单地讲,进程是执行中的应用程序。 进程不只是程序代码,还包括当前活动。包括文本段(或代码段),数据段(包括全局变量),堆(运行期间动态分配的内存),栈(临时数据,如函数参数,返回地址和局部变量),还有程序计数器和处理器寄存器的支持。
进程状态及转换
五个状态:新的(new),就绪(ready),运行(running),等待 (waiting),终止(terminated)
*状态间转换条件 一次只有一个进程可在一个处理器上运行,但是多个进程可处于就绪或等待状态
进程控制块PCB
进程控制块(PCB)
-
定义:进程控制块是操作系统用来描述进程的主要数据结构。
-
PCB 的作用 系统利用 PCB 来控制和管理进程 PCB 是进程存在的唯一标志 操作系统通过 PCB 而感知进程的存在
-
内容:
-
进程标识信息:进程ID、父进程ID等。
-
处理器状态信息:程序计数器、通用寄存器内容、处理器状态字等。
-
进程调度信息:进程状态、优先级、调度队列指针等。
-
进程控制信息:打开的文件、使用的资源、进程间通信信息等。
-
并发和并行
并发:在某一时间段内任务交替执行。 并行:多个任务同时执行。
进程调度和上下文切换
进程调度
定义:进程调度是操作系统决定哪个进程获得CPU使用权的过程。
类型:
-
长期调度(作业调度):决定哪些进程被加载到内存中。主要用于控制多道程序设计的程度。频率较低。
-
中期调度:将进程移出和调回内存,以优化内存使用,通常通过交换(swapping)实现。
-
短期调度(CPU调度):又称为CPU调度,从就绪队列中选择进程并分配CPU。该调度频繁进行,影响系统的响应时间和吞吐量。
调度准则:
-
CPU使用率:尽可能让CPU保持忙碌状态。
-
吞吐量:单位时间内完成的进程数量。
-
周转时间:从提交到完成的时间。
-
等待时间:进程在就绪队列中等待的时间总和。
-
响应时间:从提交请求到产生第一响应的时间。
上下文切换
定义:上下文切换是指操作系统将CPU从一个进程转移到另一个进程的过程。
步骤:
-
保存当前进程状态:将当前进程的CPU寄存器、程序计数器等上下文信息保存到其进程控制块(PCB)中。
-
选择新进程:从就绪队列中选择下一个进程。
-
恢复新进程状态:从新进程的PCB中恢复CPU寄存器、程序计数器等上下文信息。
-
切换到新进程:CPU开始执行新进程的指令。
影响:
-
开销:上下文切换需要一定时间,会影响系统性能。频繁的切换可能导致系统效率降低。
-
硬件支持:硬件的支持(如多组寄存器集合)可以降低上下文切换的开销。
进程操作和进程创建
进程操作
进程操作主要包括进程的创建、终止、阻塞、唤醒等。这些操作由操作系统通过系统调用来完成,确保进程在系统中能够正确地创建和管理。
进程创建
进程创建是指在操作系统中生成一个新的进程的过程。进程创建通常由一个已有的进程(父进程)来创建一个新的进程(子进程)。在UNIX和Linux系统中,常用的系统调用 fork()
用于创建进程。
进程创建的步骤:
-
分配唯一的进程标识符(PID):系统为新进程分配一个唯一的PID。
-
复制父进程的上下文:包括父进程的进程控制块(PCB)、内存空间、打开的文件描述符等。
-
分配资源:系统为新进程分配所需的资源,如内存、文件描述符等。
-
初始化新进程的PCB:设置新进程的初始状态为就绪状态。
fork()
系统调用:
-
作用:创建一个子进程。子进程是父进程的副本,除了PID和一些资源(如信号处理)。
-
返回值:在父进程中,
fork()
返回子进程的PID;在子进程中,fork()
返回0;如果创建失败,fork()
返回-1。
fork()
的两个要点:
-
上下文拷贝:内核为子进程做一个父进程的上下文拷贝,包括复制父进程的PCB作为子进程的PCB,在新的地址空间中复制父进程的内存。
-
独立运行:父进程和子进程在不同的地址空间上运行,子进程在创建后和父进程是竞争关系,两个进程依据进程调度规则分别执行。
进程树
进程树描述了系统中进程的父子关系。所有进程由根进程(如UNIX系统中的init进程)派生而来,形成一个树状结构。
进程终止
当进程完成任务或遇到不可恢复的错误时,它会终止。进程终止后,操作系统会回收它的资源,包括内存、文件描述符等。父进程通常需要调用 wait()
系列系统调用来获取子进程的终止状态,并释放其PCB。
进程间通信、消息传递、共享内存
进程间通信(Inter-Process Communication, IPC)
定义:进程间通信是指在操作系统中,多个进程之间交换数据和信息的机制。
消息传递
原理:
-
消息传递是一种直接通信方式,进程之间通过发送和接收消息来交换信息。
-
可以通过内核提供的系统调用进行通信,如
send()
和receive()
。
优点:
-
简单:实现简单,易于使用。
-
隔离性好:进程间数据隔离,安全性高。
-
适用于分布式系统:尤其适合跨计算机系统通信。
缺点:
-
速度慢:由于需要内核介入进行消息传递,速度较慢。
-
适用于小数据量:不适合传输大量数据。
共享内存
原理:
-
共享内存是一种直接通信方式,多个进程通过访问同一块内存区域进行通信。
-
需要通过系统调用
shmget()
(创建共享内存)、shmat()
(附加共享内存)等来操作共享内存。
优点:
-
速度快:进程直接访问内存,不需要内核介入,速度快。
-
适合大数据量:可以高效地传输大量数据。
缺点:
-
复杂性高:需要同步机制(如信号量)来避免并发访问冲突。
-
安全性差:进程间直接共享内存,容易出现数据不一致和安全问题。
比较
通信方式 | 优点 | 缺点 |
---|---|---|
消息传递 | 实现简单、隔离性好、适用于分布式系统 | 速度慢、适用于小数据量 |
共享内存 | 速度快、适合大数据量 | 复杂性高、安全性差 |
----线程----
线程的概念优点与引入与对比进程
线程的概念和优点
概念:
-
线程是CPU使用的基本单元,包含线程ID、程序计数器、寄存器集合和栈。
-
线程共享同一进程的代码段、数据段和其他操作系统资源,如打开文件和信号 。
优点:
-
响应度高:多线程允许一个程序在某个线程阻塞时继续执行其他线程,提高了对用户的响应。
-
资源共享:同一进程内的线程共享内存和资源,数据交换方便。
-
创建和切换开销小:线程的创建和上下文切换比进程更快,开销更小。
-
多处理器利用:在多处理器系统中,线程可以并行执行,提高系统效率 。
为什么引入线程
动机:
-
提高并发性:线程的引入是为了减少程序并发执行时的时空开销,使操作系统具有更好的并发性。
-
灵活性:线程作为调度和分派的基本单位,不频繁进行资源分配切换,提高系统效率 。
线程与进程的对比
线程:
-
基本单元:线程是CPU调度和分派的基本单元。
-
共享资源:同一进程内的线程共享进程资源,如内存和文件。
-
创建开销小:线程创建和切换开销小。
-
并发性强:线程支持更高的并发性和响应速度。
进程:
-
基本单元:进程是资源拥有和管理的基本单元。
-
独立运行:进程有独立的地址空间,彼此独立运行。
-
创建开销大:进程创建和切换开销大。
-
通信复杂:进程间通信需要通过IPC机制,复杂性高 。
多线程模型的优缺点与比较
多线程模型与优缺点
用户线程与内核线程:
-
用户线程(User-Level Threads, ULT):存在于用户空间,由线程库管理,无需内核支持,切换速度快,但如果一个线程阻塞了系统调用,整个进程会阻塞 。
-
内核线程(Kernel-Level Threads, KLT):由操作系统内核管理,线程阻塞时不会影响其他线程,但切换开销较大 。
多线程模型的比较
模型类型 | 描述 | 可创建任意多用户线程 | 并发 | 并行 |
---|---|---|---|---|
多对一模型 | 多个用户线程映射到一个内核线程。用户线程管理在用户空间进行。 | 是 | 否 | 否 |
一对一模型 | 每个用户线程映射到一个内核线程。 | 否(受限于内核线程数) | 是 | 是 |
多对多模型 | 多个用户线程映射到同等或更少数量的内核线程。 | 是 | 是 | 是 |
二级模型 | 在多对多模型基础上允许将一个用户线程绑定到一个内核线程。 | 是 | 是 | 是 |
----CPU调度----
CPU约束程序和I/O约束程序
CPU约束程序(CPU-bound Process)
-
定义:主要花费时间在计算上,很少进行I/O操作。
-
特点:需要大量的CPU时间,I/O请求不频繁。
I/O约束程序(I/O-bound Process)
-
定义:主要花费时间在I/O操作上,计算时间较少。
-
特点:频繁进行I/O操作,CPU时间需求少
**CPU调度程序,调度策略和算法(周转,等待时间)
定义
-
CPU调度程序(也称为短期调度程序)负责在CPU空闲时,从就绪队列中选择一个合适的进程分配给CPU。
调度时机
-
进程从运行状态切换到等待状态(如I/O请求)。
-
进程从运行状态切换到就绪状态(如中断发生)。
-
进程从等待状态切换到就绪状态(如I/O完成)。
-
进程结束时。
调度策略和算法
1. 先到先服务调度算法(FCFS)
-
描述:按照进程到达就绪队列的顺序分配CPU。
-
优点:简单易实现。
-
缺点:平均等待时间长,可能导致护航效应。
2. 最短作业优先调度算法(SJF)
-
描述:选择CPU时间最短的进程优先执行。
-
优点:平均等待时间最短。
-
缺点:难以预知下一个CPU区间的长度,可能导致长进程饥饿。
3. 最短剩余时间优先调度算法(SRTF)
-
描述:SJF的抢占式版本,选择剩余CPU时间最短的进程执行。
-
优点:提高系统吞吐量。
-
缺点:可能导致长进程饥饿,复杂度高。
4. 轮转调度算法(RR)
-
描述:每个进程分配一个时间片,时间片结束后切换到下一个进程。
-
优点:公平,每个进程都能得到执行机会。
-
缺点:时间片选择不当会影响性能。
5. 优先级调度算法
-
描述:根据进程的优先级分配CPU,优先级高的进程优先执行。
-
优点:可以满足不同进程的优先需求。
-
缺点:可能导致低优先级进程饥饿,需引入老化机制防止饥饿。
(FCFS)
(SJF)
调度算法评估
调度算法评估
调度算法 | CPU使用率 | 吞吐量 | 周转时间 | 等待时间 | 响应时间 | 公平性 | 开销 |
---|---|---|---|---|---|---|---|
先到先服务(FCFS) | 一般 | 一般 | 可能较长 | 可能较长 | 可能较长 | 高 | 低 |
最短作业优先(SJF) | 高 | 高 | 短 | 短 | 较短 | 低 | 中 |
最短剩余时间优先(SRTF) | 高 | 高 | 更短 | 更短 | 短 | 低 | 高 |
轮转调度(RR) | 一般 | 一般 | 一般 | 一般 | 较短 | 高 | 中 |
优先级调度 | 视情况而定 | 视情况而定 | 视情况而定 | 视情况而定 | 视情况而定 | 低到中 | 视实现复杂度而定 |
----进程同步----
临界区critical section以及解决方案四原则
临界区 critical section:程序中访问临界资源的那段代码,要将对临界资源的互斥访问转化为对临界区的互斥访问,即没有两个进程同时在临界区内执行
临界区问题解答方案的原则 (1) 互斥 mutual exclusion:忙则等待。进程不同时在临界区内执行 (2) 前进 prograss:有空让进。当无进程在临界区执行时,若有进程进入应允许 (3) 有限等待 bounded waiting:进程进入临界区的要求必须在有限时间内得到满足 (4) 让权等待 no busy waiting:等待的时候可以选择释放 CPU 执行权(非必须)
有两种方式用于处理操作系统内的临界区问题:抢占内核和非抢占内核。非抢占内核不允许处于内核模式的进程被抢占,根本不会导致竞争条件,因为只能有一个进程处于内核模式。但是抢占内核需要认真设计才能保证不会导致竞争条件。
硬件同步解决临界区问题
硬件同步是利用硬件提供的原子操作来实现临界区的互斥访问。以下是常见的硬件同步方法:
1. 禁用中断
原理:
-
在进入临界区之前禁用中断,退出临界区后再启用中断。
-
这样可以保证当前正在执行的代码不会被中断,从而实现临界区的互斥访问。
优点:
-
实现简单,适用于单处理器系统。
缺点:
-
禁用中断时间过长会影响系统响应性。
-
不适用于多处理器系统,因为只禁用当前处理器的中断,其他处理器仍可并行执行。
2. Test-and-Set指令
原理:
-
Test-and-Set是一种原子操作,用于测试和设置一个标志位。
-
当一个进程要进入临界区时,使用Test-and-Set指令检查并设置一个锁变量。如果锁变量为0,则设置为1并进入临界区;否则,继续等待。
-
(1) 指令 TestAndSet()主要特点是可以原子的执行,即两个指令在不同 CPU 上执行时会按顺序执行。使用这个指令需要声明一个 boolean 变量 lock 初始化为false 这个指令的作用是返回 target 的现在的值并将 target 设置为 true。它的使用方法是,每一个进程都不停地执行这个指令直到发现 lock 为 false,说明 lock 正处于初识状态或者另一个占用临界区的进程已经解锁 lock
伪代码:
优点:
-
原子操作,保证了临界区的互斥访问。
-
实现简单,高效。
缺点:
-
可能导致忙等待(busy waiting),浪费CPU时间。
3. Swap指令
原理:
-
Swap指令交换两个变量的值。
-
利用Swap指令,可以实现进程对锁变量的原子检查和设置,从而实现临界区的互斥访问。
-
其工作原理基本相似,进程不停地交换 lock 和 key 值,只有初始 lock=false的时候或者另一个进程释放资源将 lock 设置为 false 的时候,交换获得的 key 值才能为 false,进程才能跳出循环
伪代码:
优点:
-
原子操作,保证了临界区的互斥访问。
缺点:
-
可能导致忙等待,浪费CPU时间。
简单了解一下Peterson算法
Peterson算法是一个经典的同步算法,用于解决两个进程之间的临界区问题。它经历了三个阶段的发展:
-
使用令牌:
-
通过turn变量给一个进程令牌,持有令牌的进程进入临界区。
-
问题:持有令牌的进程不执行时,另一个进程会无限等待,不符合progress原则。
-
-
登记簿:
-
使用flag数组记录进程是否想进入临间区。
-
问题:两个进程同时到达时,互相看到对方已登记,互相谦让,陷入无限循环,不符合progress原则和有限等待原则。
-
-
使用登记簿和令牌:
-
进程欲进入临界区时,登记并将令牌移交给对方。如果对方已登记且持有令牌,则等待;否则进入临界区。
-
解决了上述问题,但仅适用于两个进程共享资源的情况。
-
总结:Peterson算法通过综合使用登记簿和令牌,实现了两个进程间的互斥访问,确保了同步的三个要求:互斥、进程等待和有限等待。尽管仅适用于两个进程,但它提供了理解和设计同步机制的重要思路。
****信号量的定义
好的,作为操作系统老师,我会从基础开始,详细讲解信号量(Semaphore)。
什么是信号量?
信号量是一种用于进程同步的机制,可以用于解决多个进程访问共享资源时的互斥和协调问题。它是由荷兰计算机科学家Dijkstra发明的。
信号量的类型
-
计数信号量(Counting Semaphore):
-
它是一个整数,可以用来控制对多个资源的访问。
-
初始值通常为资源的数量。
-
当资源被占用时,信号量的值减一;当资源被释放时,信号量的值加一。
-
-
二进制信号量(Binary Semaphore):
-
只有两个值0和1,类似于互斥锁(Mutex)。
-
用于实现对单个资源的互斥访问。
-
信号量的基本操作
信号量主要有两个基本操作:P操作(Wait)和V操作(Signal)。
-
P操作(Wait,减一操作):
-
检查信号量的值是否大于0。如果大于0,将信号量减一,并继续执行。
-
如果信号量的值等于0,进程进入等待状态,直到信号量的值大于0。
-
-
V操作(Signal,加一操作):
-
将信号量的值加一。
-
如果有进程在等待信号量,将唤醒一个等待的进程。
-
-
信号量的工作原理
举个例子:
假设有一个资源可以被多个进程共享。我们可以使用一个计数信号量来管理这个资源的访问。
-
初始状态:
-
信号量的值设为资源的数量,比如3个资源,信号量初始值为3。
-
-
进程访问资源:
-
当一个进程想访问资源时,执行P操作。信号量值减一,比如从3减到2。
-
如果信号量值为0,表示没有可用资源,进程进入等待状态。
-
-
进程释放资源:
-
当进程使用完资源时,执行V操作。信号量值加一,比如从2加到3。
-
如果有进程在等待资源,被唤醒的进程将继续执行。
-
使用信号量的例子
假设有两个进程A和B,它们需要互斥地访问一个共享变量。我们可以使用一个二进制信号量来实现互斥。
-
初始化:
-
信号量初始值设为1。
-
-
进程A执行:
-
进程A想访问共享变量,执行P操作。如果信号量值为1,减一后继续执行。
-
进程A执行完后,执行V操作,信号量值加一,释放资源。
-
-
进程B执行:
-
进程B想访问共享变量,也执行P操作。如果信号量值为0,进程B等待。
-
当进程A释放资源后,进程B被唤醒,继续执行。
-
信号量的优点
-
简化同步:通过P和V操作,简化了进程间的同步问题。
-
解决互斥:有效解决多个进程对共享资源的互斥访问问题。
-
灵活性高:可以用于多种同步场景,不仅限于互斥锁。
****信号量伪代码
两进程合作问题三要素:信号量设置、信号量初值、算法描述;
信号量:同一信号量 P、V 必须成对出现,互斥信号量必须成对出现在一个程序中,资源信号量出现在不同程序中;
多个 wait 操作顺序是:同步在前、互斥在后;
1.生产者消费者问题
生产者消费者问题(有限缓冲问题)Bounded-Buffer 问题描述:缓冲池中有 n 个缓冲项,每个缓冲项能存一个数据,有多个生产者向缓冲池中送数,同时有多个消费者从缓冲池中取数。所有生产者消费者因为都要修改缓冲池,所以必须要互斥。
生产者等待消费者取数,消费者等待生产者放数,二者等待的信号量不是同一信号量。同时,由于互斥访问,还需要加一个互斥锁
Shared data semaphore empty,full,mutex(互斥); Initially: empty= n,full=0,mutex=1;
(buffer缓冲)
2.读者写者问题 Readers and Writers
问题描述:一个数据库被多个并发进程共享,有的进程只需要读数据库,读者不需要互斥;有的进程需要写数据库,写者之间必须互斥并且与读者互斥。写者进程比较简单,只需要实现简单的互斥。 对于读者,有两个比较重要:第一个进入的和最后一个离开的。第一个进入的应该拒绝写者但不能拒绝其他读者;最后一个离开的应唤醒写者。因此需要一个计数器记录读者个数。计数器被读者共享,需要互斥锁。
初始值:
Semaphore mutex=1,wrt=1;
int readcount=0;
3.哲学家就餐问题 Dining-Philosophers(管程)
问题描述:五个哲学家用五支筷子在一个圆桌上就餐,每个哲学家需要两只筷子吃饭。 最简单的方法是分别为五支筷子设置信号量初始化为 1,每个哲学家的进程都是申请两只筷子吃饭然后释放。
Semaphore chopstick[5];
4.睡眠理发师问题
问题描述:某理发店有一个接待室和一个理发室组成。理发室中有一把理发椅,接待室中有 n 把椅子。若没有顾客等待理发,则理发师睡眠等待。当一个顾客到达理发店后,若发现座位已满,则选择离开;若发现理发师忙而接待室中有空座位,顾客则坐在椅子上等待;若发现理发师正在睡眠,则将理发师唤醒。 问题分析: 理发师:发现有顾客,则呼叫下一个,否则等待 顾客:到达理发店,没有空座位则离开;否则告诉理发师有人在等待然后坐下等待理发师呼叫 需要整型变量 waiting=0 记录等待的顾客数,互斥锁 barber=0 记录理发师是否可以服务,互斥锁 mutex=1 实现对 waiting 的互斥访问。记住,这个模型初识状态是理发师在睡觉,需要被唤醒
5.吸烟者问题
问题描述:一支烟需要三种材料,系统中有三个吸烟者每人各有一种材料同时有一个进程随机供应两种材料。吸烟者等待适配的材料然后抽烟。 三个吸烟者进程,一个供应者进程,三个供应材料信号,一个吸烟结束信号。以一个吸烟者为例:
管程(Monitor)
-
定义:
-
管程是一种高级同步机制,它封装了共享资源和对这些资源的操作,同时提供了条件变量来管理线程的等待和唤醒。
-
-
使用方法:
-
管程通过互斥锁确保只有一个线程可以进入管程,执行其中的代码。
-
使用条件变量来管理线程的等待和唤醒。
-
-
封装性:
-
管程将共享资源和操作封装在一个结构中,提供了清晰的接口,隐藏了同步的细节。
-
什么是条件变量?
条件变量是管程中的一个重要概念,用于让线程等待某个特定条件的发生。条件变量主要用于线程同步,它使得一个线程可以等待另一个线程发出的信号,从而协调多个线程的执行顺序。
管程的基本原理是通过互斥锁和条件变量来管理并发访问,确保共享资源的安全使用。
管程的工作方式:
互斥锁:
-
管程使用互斥锁(Mutex)来确保只有一个线程可以在任何时候进入管程。
-
当一个线程进入管程时,它会锁住管程,其他线程必须等待,直到该线程离开管程并释放锁。
条件变量:
-
管程内部使用条件变量来管理线程的等待和唤醒。
-
线程在执行过程中,如果发现某个条件不满足,就会在相应的条件变量上等待。
-
其他线程在改变共享资源状态后,会使用条件变量发出信号,通知等待的线程继续执行。
----死锁----
死锁(Deadlock)概念&对比饥饿
概念: 死锁是指两个或多个进程相互等待对方释放资源,而导致它们都无法继续执行的情况。换句话说,每个进程都持有某些资源并等待其他进程持有的资源,导致所有进程都无法前进。
饥饿(Starvation)
概念: 饥饿是指某个进程长时间无法获取所需资源,导致无法执行的情况。饥饿发生在资源调度策略不公平的情况下,使得某些进程一直得不到资源。
死锁与饥饿的对比
特性 | 死锁(Deadlock) | 饥饿(Starvation) |
---|---|---|
定义 | 进程相互等待对方释放资源,导致所有进程无法继续执行。 | 进程长时间无法获取所需资源,导致无法执行。 |
原因 | 资源的互斥使用、持有并等待、不剥夺和循环等待。 | 资源分配策略不公平,某些进程长期得不到资源。 |
状态 | 系统中进程陷入永久等待状态。 | 系统中进程一直处于等待状态,但系统仍在运行。 |
检测 | 可以通过资源分配图等方法检测。 | 通常较难检测,需要关注资源调度策略。 |
解决 | 需要打破死锁的四个必要条件之一。 | 通过公平的资源分配策略、优先级老化等方法解决。 |
总结
-
死锁是进程相互等待资源而无法继续执行的情况,需要满足互斥条件、持有并等待条件、不剥夺条件和循环等待条件。解决死锁通常需要打破这四个条件之一。
-
饥饿是进程长时间无法获取资源导致无法执行的情况,通常是由于资源分配策略不公平导致的。解决饥饿需要采用公平的资源分配策略或优先级老化等方法。
**死锁4个必要条件&预防死锁
死锁的四个必要条件:
-
互斥条件(Mutual Exclusion):至少有一个资源必须是非共享的,即一次只能被一个进程占用。
-
持有并等待条件(Hold and Wait):一个进程至少持有一个资源,同时等待获取由其他进程持有的资源。
-
不剥夺条件(No Preemption):资源不能被强制剥夺,只能由持有该资源的进程主动释放。
-
循环等待条件(Circular Wait):存在一个进程集合,每个进程都在等待集合中的下一个进程所持有的资源。
死锁的预防方法
为了防止死锁的发生,可以采取以下预防方法,确保系统在资源分配和进程调度时避免死锁的四个必要条件:
-
破坏互斥条件:
-
尽量减少资源的互斥使用,尽量使资源可共享。例如,尽量使用可共享的资源,如读写锁而不是独占锁。
-
-
破坏持有并等待条件:
-
一次性分配所有资源:进程在开始执行前,必须一次性申请并获得它所需要的所有资源。如果所有资源都可以一次性获得,则继续执行;否则,进程必须等待所有资源都可用。
-
进程持有资源时不再申请新的资源:要求进程在持有资源期间不再申请新的资源。进程在进入等待状态前必须释放已经持有的资源,然后重新申请所有资源。
-
-
破坏不剥夺条件:
-
可剥夺资源:如果一个进程已经占有某些资源但又申请新的资源而得不到,可以让该进程释放它已经占有的资源,稍后再重新申请。例如,使用可剥夺的锁或实现资源的回收机制。
-
-
破坏循环等待条件:
-
顺序资源分配法:为系统中的所有资源编号,要求进程按照编号顺序申请资源。例如,进程持有编号为
i
的资源时,只能申请编号大于i
的资源。 -
按序请求资源:在系统中规定一种资源请求的全序关系,进程必须按序请求资源,避免形成循环等待。例如,先申请低编号资源,再申请高编号资源。
-
总结
通过破坏死锁的四个必要条件之一,可以有效预防死锁的发生。具体方法包括:
-
破坏互斥条件:尽量使用可共享资源。
-
破坏持有并等待条件:一次性分配所有资源或进程持有资源时不再申请新的资源。
-
破坏不剥夺条件:实现可剥夺资源机制。
-
破坏循环等待条件:使用顺序资源分配法或按序请求资源。
这些方法通过不同策略,确保进程在资源申请和释放过程中不会形成死锁,从而提高系统的稳定性和效率。
死锁的避免与检测
死锁的避免
死锁的避免通过动态检测和避免可能导致死锁的资源分配来实现。主要方法包括银行家算法。
银行家算法:
-
基本思想:在分配资源前,系统模拟资源分配,判断是否会进入不安全状态。如果不会进入不安全状态,则分配资源,否则进程必须等待。
-
步骤:
-
计算可用资源。
-
计算每个进程的最大需求和当前需求。
-
判断是否存在一个进程可以满足其最大需求并继续执行,如果存在,假设分配资源并更新状态,继续判断其他进程;如果不存在,则系统进入不安全状态,不分配资源。
-
判断是否在安全状态以及是否是死锁
示例
假设有3个进程(P1、P2、P3)和3类资源(A、B、C)。系统资源总量为:A=10, B=5, C=7。当前分配情况如下:
进程 | 已分配 | 最大需求 | 剩余需求 |
---|---|---|---|
P1 | 3, 0, 2 | 7, 5, 3 | 4, 5, 1 |
P2 | 2, 1, 0 | 3, 2, 2 | 1, 1, 2 |
P3 | 2, 1, 1 | 9, 0, 2 | 7, -1, 1 |
当前可用资源为:A=3, B=2, C=2。
-
判断是否在安全状态:
-
计算当前系统可用资源:A=3, B=2, C=2。
-
尝试找到一个满足需求的进程:
-
P2的剩余需求是1, 1, 2,可以满足。
-
假设分配给P2后,P2完成,释放其资源:A=5, B=3, C=2。
-
更新系统可用资源:A=5, B=3, C=2。
-
-
继续判断其他进程:
-
P1的剩余需求是4, 5, 1,当前可用资源无法满足。
-
P3的剩余需求是7, -1, 1,当前可用资源无法满足。
-
因此,系统不在安全状态。
-
-
判断是否是死锁:
-
检查资源分配图或等待图:
-
如果系统进入不安全状态,并且存在资源请求被无限期推迟的情况,则可能存在死锁。
-
检查P1和P3的请求是否能够被满足。
-
P1和P3都无法被满足,可能存在死锁。
-
-
内存管理
地址绑定&三个时间
地址绑定的概念
地址绑定是指将程序中的逻辑地址(符号地址或虚拟地址)转换为物理地址的过程。地址绑定可以在不同的时间进行,根据绑定的时机不同,系统可以选择在编译时、装入时或执行时进行地址绑定。
三个绑定的时机
-
编译时绑定:
-
概念:在编译期间,程序的逻辑地址被直接转换为物理地址。
-
特点:生成的可执行文件中的地址是固定的,不能改变。
-
适用场景:适用于程序在固定的内存位置运行,适合简单的系统。
-
-
装入时绑定:
-
概念:在程序装入内存时,逻辑地址被转换为物理地址。
-
特点:程序加载到内存时分配地址,装入后地址固定不变。
-
适用场景:适用于程序在装入内存后不再移动的系统。
-
-
执行时绑定:
-
概念:在程序执行期间,通过硬件支持(如MMU,内存管理单元),将逻辑地址动态转换为物理地址。
-
特点:允许程序在执行期间在内存中移动,提供了更大的灵活性和高效的内存利用。
-
适用场景:适用于多任务操作系统和需要内存动态分配的复杂系统。
-
总结
地址绑定是将逻辑地址转换为物理地址的过程,可以在编译时、装入时或执行时进行。不同的绑定时机提供了不同的灵活性和适用场景:
-
编译时绑定:地址在编译时确定,适用于固定内存位置的简单系统。
-
装入时绑定:地址在装入内存时确定,适用于装入后不再移动的系统。
-
执行时绑定:地址在执行期间动态确定,适用于需要动态内存管理的复杂系统。
逻辑地址&物理地址&动态加载&动态链接
(1)
逻辑地址空间:CPU 生成的地址称为逻辑地址(也称虚拟地址),由程序所生成的所有逻辑地址的集合叫逻辑地址空间。
物理地址空间:内存单元的地址叫做物理地址,与程序的逻辑地址空间所对应的为物理地址空间。
(2)映射:虚拟地址到物理地址的映射由内存管理单元(MMU)完成,此处先用一个简单的映射方式介绍:利用一个基地址寄存器(此处称为重定位寄存器)完成映射,如下图: 若逻辑地址范围为 0~max,基地址为14000,则对应的物理地址为 14000~14000+max
(3)加载:
动态加载: 定义:主程序装入内存执行,当一个子程序需要被调用时将其装入内存。 优点:提高了内存的利用率 缺点:管理复杂,执行速度慢。
绝对方式加载:在进程执行前将其所有模块都装入内存。内存利用率低,但是执行速度快,管理简单。
(4)链接: 静态链接: 定义:运行前将所有程序模块链接在一起,形成可执行文件,运行时直接装入内存。 优点:运行速度快。 缺点:链接及装入过程费时,可能装入用不到的模块,不利于模块的升级。
动态链接: 定义:运行时链接,且仅链接需要的模块。 优点:便于模块的升级,减少了链接的时间,节省内存空间。 缺点:运行速度慢。
**连续内存分配&分配方法&分配算法
连续内存分配
定义: 连续内存分配是一种内存管理方式,将整个进程的所有内存需求分配在一块连续的物理内存区域中。
主要方法及碎片类型
-
单一分区分配:
-
概念:内存分为两个部分,一个部分留给操作系统,另一部分留给一个用户进程。
-
特点:实现简单,但只适用于单用户系统。
-
碎片类型:不会产生碎片,因为只有一个用户进程占用内存。
-
-
固定分区分配:
-
概念:内存被划分为多个固定大小的分区,每个分区只能容纳一个进程。
-
特点:简单但可能导致内存碎片,不能灵活适应进程大小变化。
-
碎片类型:产生内部碎片。因为进程的内存需求可能小于分区大小,导致分区内部未使用的部分成为碎片。
-
-
可变分区分配:
-
概念:内存按需分配,进程需要多少内存就分配多少,未分配的内存保留为一个大空闲区。
-
特点:灵活但可能导致内存碎片,需要进行内存压缩(紧凑)来合并空闲块。
-
碎片类型:产生外部碎片。由于内存按需分配和释放,导致内存中出现不连续的空闲块,使得总空闲内存不足以满足新的进程需求。
-
分配算法及碎片类型
-
首次适配(First-Fit):
-
概念:从头开始查找,找到第一个足够大的空闲块进行分配。
-
优点:实现简单,速度快。
-
碎片类型:产生外部碎片。由于分配时选择第一个合适的空闲块,可能导致大量小的空闲块散布在内存中。
-
-
最佳适配(Best-Fit):
-
概念:查找所有空闲块,找到最适合的最小空闲块进行分配。
-
优点:减少大块空闲区的浪费,但可能导致较多的小碎片。
-
碎片类型:产生外部碎片。由于选择最小的合适空闲块进行分配,可能导致大量小的空闲块无法利用。
-
-
最坏适配(Worst-Fit):
-
概念:查找所有空闲块,找到最大的空闲块进行分配。
-
优点:减少小碎片的数量,但可能浪费大块内存。
-
碎片类型:产生外部碎片。由于选择最大的空闲块进行分配,可能导致大块空闲内存被浪费,形成零散的小碎片。
-
**分页分配
连续内存分配存在严重的碎片问题,并且为较大作业分配足够大的内存区域比较困难。分页分配通过将内存和逻辑地址空间划分为固定大小的块来解决这些问题。
基本概念
-
页(Page):将逻辑内存分成的固定大小的块。
-
帧(Frame):将物理内存分成的固定大小的块。
-
页表(Page Table):将页和帧进行映射(逻辑地址到物理地址的映射)。
-
逻辑地址格式:逻辑地址由页号和页内偏移量组成。
-
帧表(Frame Table):记录内存分配的细节,如哪些帧已用,哪些帧可用,总帧数等。
基本思想
-
一个作业在内存的各个页面可分配到不同帧中,但每个页面是连续的。
-
用户视角的内存和实际的物理内存分离。
-
内存分帧,作业分页,帧的大小和页的大小相同。
-
内存分配以页为单位,会产生内部碎片。
地址映射过程&逻辑地址到物理地址的转换
逻辑地址到物理地址的转换
-
逻辑地址 = 页号 + 页内偏移量。
-
使用页号查找页表,得到帧号。
-
物理地址 = 帧号 * 帧大小 + 页内偏移量。
查页表过程&地址转换过程
-
提取页号和页内偏移量:
-
从逻辑地址中提取页号(P)和页内偏移量(d)。
-
-
页表基址:
-
页表基址寄存器(PTBR)提供页表的起始地址。
-
-
索引页表:
-
使用页号(P)索引页表,获取对应的页框号(F)。
-
-
计算物理地址:
-
将页框号(F)与页内偏移量(d)组合,形成物理地址。
-
总结
从逻辑地址到物理地址的转换通过以下步骤进行:
-
提取逻辑地址中的页号和页内偏移量。
-
使用页号索引页表,获取对应的页框号。
-
计算物理地址 = 页框号 * 页大小 + 页内偏移量。
示例
假设系统有如下设置:
-
页大小:4KB
-
页表长度:4(表示页号为0到3)
-
页表内容:
-
页0 -> 页框1
-
页1 -> 页框4
-
页2 -> 页框3
-
页3 -> 页框7
-
示例1:合法地址
逻辑地址:0x1004
(即二进制 0001 0000 0000 0100
)
-
页号(P):
00 01
(二进制),即1 -
页内偏移量(d):
0000 0000 0100
(二进制),即4
转换过程:
-
从逻辑地址中提取页号1和偏移量4。
-
使用页号1索引页表,得到页框号4。
-
计算物理地址:物理地址 = 页框号4 * 页大小4KB + 偏移量4 = 4 * 4KB + 4 = 16KB + 4 = 16388。
分页分配中的内存保护&页表中的标志位与有效位
内存保护: 分页分配通过页表和标志位来实现内存保护,确保进程只能访问其被允许的内存区域,防止非法访问和内存越界。
页表中的标志位
-
有效位(Valid Bit):
-
定义:表示页表项是否有效。
-
作用:用于判断页表项是否指向一个有效的物理页框。
-
转化成功:如果有效位为1,表示该页在内存中,可以进行地址转换。
-
转化失败:如果有效位为0,表示该页不在内存中,可能在硬盘上或不存在,需要进行页面调度或产生缺页异常。
-
-
读/写位(Read/Write Bit):
-
定义:表示该页是否允许写操作。
-
作用:用于控制内存访问权限,防止未授权的写操作。
-
使用场景:只读数据段页设置为只读,写操作会触发异常。
-
-
用户/内核位(User/Supervisor Bit):
-
定义:表示该页是否可以由用户模式访问。
-
作用:区分用户模式和内核模式的访问权限,防止用户进程访问内核内存。
-
使用场景:内核代码和数据页设置为内核模式,用户模式访问会触发异常。
-
内存保护机制
-
页号与页表长度比较:
-
过程:当进程要访问某个逻辑地址时,首先将页号与页表长度进行比较。
-
判断:如果页号大于或等于页表长度,则表示访问越界,产生地址越界异常。
-
-
有效位检查:
-
过程:从逻辑地址提取页号,通过页号在页表中查找对应的页表项。
-
判断:检查页表项的有效位。
-
有效位为1:表示该页在内存中,可以进行地址转换。
-
有效位为0:表示该页不在内存中,产生缺页异常,需要从硬盘调入页。
-
-
-
权限检查:
-
读/写位检查:检查是否允许写操作,如果不允许且发生写操作,则产生访问权限异常。
-
用户/内核位检查:检查访问权限,如果用户模式进程试图访问内核模式页,则产生访问权限异常。
-
总结
分页分配中的内存保护通过页表中的标志位实现,包括有效位、读/写位和用户/内核位。这些标志位确保进程只能访问其被允许的内存区域,防止非法访问和内存越界。具体机制如下:
-
页号与页表长度比较:防止地址越界。
-
有效位检查:判断页是否在内存中,决定是否进行地址转换。
-
权限检查:控制读写权限和用户/内核模式访问权限。
通过这些机制,分页分配提供了有效的内存保护,确保系统的安全性和稳定性。
分段&段页的概念和好处
分段分配
概念: 分段分配是一种内存管理方式,将程序的逻辑地址空间划分为若干段(Segment),每段代表一个逻辑单元,如代码段、数据段和堆栈段。每段独立分配,段与段之间可以不连续。
好处:
-
逻辑性强:每段表示一个完整的逻辑单元,符合程序结构。
-
灵活性高:段大小可变,适应不同程序的需要。
-
保护和共享:段可以单独设置保护和共享属性,方便内存保护和进程间共享。
分页分段结合分配
概念: 分页分段结合分配是一种内存管理方式,将分段和分页结合起来。首先将程序划分为若干段,每段再划分为若干页。段表用于管理段的信息,页表用于管理每段内页的信息。
好处:
-
减少外部碎片:通过分页解决分段中的外部碎片问题。
-
高效内存利用:段可以独立扩展,每段内存分页管理,提高内存利用率。
-
综合优点:结合了分段和分页的优点,既有分段的逻辑性和灵活性,又有分页的内存利用效率和管理简便性。
总结
-
分段分配:
-
概念:将程序的逻辑地址空间划分为若干独立的段。
-
好处:逻辑性强,灵活性高,便于内存保护和共享。
-
-
分页分段结合分配:
-
概念:将程序首先划分为段,每段再划分为页,段表管理段,页表管理页。
-
好处:减少外部碎片,提高内存利用率,综合分段和分页的优点。
-
---虚拟内存---
请求分页,按需调页
请求分页,按需调页
定义:
调用程序时在需要时才调入相应的页,使用懒惰交换(只有在需要页时才调 入
优点: I/O 时间低,所需内存减少,更快响应,并发度更高
缺页中断:所需页不在内存中(标志位为 invalid),引发页面错误
若内存未满,则找到一个空闲帧放入所需页。内存已满,需要替换出一个页,将 3 号页放入空闲帧(需要进行页面置换)。
缺页中断和一般中断的区别:普通中断是在 CPU 完成对该指令的执行后检 查和处理中断,而缺页中断是在指令执行期间,发现所需指令或数据不在内存时产生和处理的
缺页中断率 p 越接近 0,性能越高
**页面置换算法
查找所需页在磁盘中的位置;查找空闲帧,若找到则使用,若未找到,则使用页置换算法来选择一个“牺牲”帧(victim frame),将“牺牲”帧的内容写入磁盘,改变帧表和页表;将所需页写入空闲帧,改变页表和帧表;重启用户进程。
最小页错误率算法:用于评价页置换算法(帧分配算法也适用)
页面置换算法
1. 最佳置换算法(Optimal Algorithm, OPT)
概念:
-
选择未来最长时间内不再使用的页面进行替换。
优点:
-
理论上最优,可以实现最少的缺页中断。
缺点:
-
需要知道未来的页面访问顺序,实际系统中无法实现,通常作为其他算法的比较标准。
示例:
-
假设内存中的页面序列为 {1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5},OPT算法会选择未来最久不使用的页面进行替换
2. 先进先出算法(FIFO, First-In-First-Out)
概念:
-
替换最早进入内存的页面,即驻留时间最长的页面。
优点:
-
实现简单,维护一个先进先出的队列即可。
缺点:
-
可能会出现Belady异常,即增加内存帧数反而增加缺页率
示例:
-
页序列为 {1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5},使用FIFO算法时,最早进入内存的页面将被替换
3. 最近最少使用算法(LRU, Least Recently Used)
概念:
-
替换最近最久未使用的页面,基于时间局部性原理。
优点:
-
性能较好,没有Belady异常。
缺点:
-
实现复杂,需要维护页面的使用记录,可能需要硬件支持。
示例:
-
页序列为 {1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5},使用LRU算法时,最近最久未使用的页面将被替换
4. 时钟算法(Clock Algorithm)
概念:
-
近似LRU算法,维护一个循环队列和一个指针,引用位用于决定是否替换页面。
优点:
-
实现比LRU简单,性能接近LRU。
缺点:
-
仍需要硬件支持来维护引用位。
示例:
-
页序列为 {1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5},使用时钟算法时,通过引用位和指针选择替换的页面
5. 基于计数的页面置换算法
概念:
-
维护每个页面的引用计数,根据计数选择替换页面。
分类:
-
最不经常使用(LFU, Least Frequently Used):替换引用次数最少的页面。
-
最经常使用(MFU, Most Frequently Used):替换引用次数最多的页面。
优点:
-
可以根据页面使用频率做出决策。
缺点:
-
需要维护计数器,可能增加开销。
示例:
-
页序列为 {1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5},使用LFU算法时,引用次数最少的页面将被替换
****帧分配&空闲帧管理
帧分配(Frame Allocation)
帧分配是指如何将物理内存中的帧分配给各个进程。合理的帧分配策略能够有效利用内存资源,提高系统性能。根据《操作系统第七版重点总结》的内容,帧分配策略主要包括以下几种:
-
最少最大帧数量
-
每个进程所需的最少帧数量由计算机体系结构决定,而最大帧数量由物理内存数量决定。
-
-
帧分配算法
-
平均分配:将内存中所有可用的帧平均分配给所有进程。例如,有93个帧和5个进程,每个进程分得18个帧,剩余3个帧放入空闲帧缓冲池。
-
比例分配:根据进程的虚拟内存大小或优先级来按比例分配帧。例如,进程的虚拟内存越大或优先级越高,分配的帧数越多。
-
-
全局置换和局部置换
-
全局置换:进程可以从所有帧中选择一个进行置换,不管这个帧是否分配给其他进程。优点是系统吞吐量更大;缺点是进程无法控制其页错误率。
-
局部置换:进程只能从分配给自己的帧中选择置换帧。优点是可以控制进程的页错误率;缺点是可能无法充分利用内存
-
-
优先级分配
-
当一个进程发生页错误时,可以选择从已分配给自己的帧中或从优先级较低的进程中选择一个帧进行置换
-
空闲帧管理(Free Frame Management)
空闲帧管理用于跟踪物理内存中哪些帧是空闲的,并在需要时将这些帧分配给进程。主要方法包括:
-
位图法(Bitmap Method)
-
使用位图记录每个帧的状态,每个位对应一个物理帧,0表示空闲,1表示已使用。优点是方法简单,适合较小规模的内存管理;缺点是在大型内存系统中效率较低
-
-
链表法(Linked List Method)
-
将所有空闲帧链接成一个链表,分配帧时从链表头取出一个空闲帧。优点是分配和回收效率较高,适合动态内存管理;缺点是需要额外的指针存储空间
-
-
页面缓冲算法(Page Buffering Algorithm)
-
系统维护一个空闲帧缓冲池,当发生页错误时,可以直接从池中选择一个空闲帧进行使用。这种方法可以加快进程的重启速度,减少因页错误导致的延迟
-
Thrashing颠簸&抖动的原因和解决方案
颠簸和抖动的原因
定义: 颠簸(Thrashing)是指系统中频繁发生页面置换,导致CPU的大部分时间都用于页面调度而不是实际计算。具体表现为:一个页面刚被替换出去,又很快需要被访问,导致频繁的页面换入换出。
原因:
-
内存不足:进程没有足够的帧来容纳其工作集,导致频繁的页面调度。
-
过度的多道程序度:系统中的进程数量过多,内存无法满足所有进程的需求。
-
CPU利用率与页调度:当系统检测到CPU利用率较低时,会增加多道程序度,引入更多进程。这些新进程需要帧,导致更频繁的页调度,形成恶性循环
解决方案
1. 局部置换或优先级置换算法
-
局部置换:进程只能从自己分配的帧中选择进行置换,避免一个进程的抖动影响到其他进程。
-
优先级置换:高优先级进程发生页错误时,可以从低优先级进程中选择帧进行置换,减少高优先级进程的页调度频率
2. 工作集模型(Working Set Model)
-
原理:基于局部性原理,为每个进程分配足够的帧以容纳其工作集,防止抖动。工作集是进程在一段时间内实际使用的页面集合。
-
WSS(工作集大小):表示工作集中页面的数目,若系统中所有进程的WSS之和超过物理内存总量,就会发生抖动
3. 页错误频率策略(Page-Fault Frequency Scheme)
-
思想:为期望的页错误频率设置上下限。当进程的页错误频率超过上限时,增加其分配的帧;当页错误频率低于下限时,减少其分配的帧
4. 减少多道程序度
-
方法:降低系统中的进程数量,使每个进程有足够的帧来减少页调度。
-
效果:降低页错误率,提高CPU利用率
5. 增加物理内存
-
方法:通过增加系统的物理内存来缓解内存紧张的情况。
-
效果:更多的页面可以驻留在内存中,减少频繁的页调度
**页大小
页表大小:页越大,页表条目越少,页表越小,管理开销也越小。
内存利用率:较小的页可以更高效地利用内存,减少浪费。
页读写时间:较大的页可以减少I/O操作的频率,优化I/O性能。
页错误率:较大的页可以减少页错误的发生,提高程序的执行效率。
页大小的选择
页越大越好的情况
-
大数据处理和科学计算
-
原因:减少页表条目,降低管理开销,减少I/O操作次数和页错误率。
-
示例:数据库系统、大数据分析。
-
-
高吞吐量I/O操作
-
原因:提高I/O带宽利用率。
-
示例:流媒体服务、大文件传输。
-
-
虚拟机和容器
-
原因:减少页表大小,提高内存管理效率。
-
示例:虚拟化平台、容器编排系统。
-
页越小越好的情况
-
高内存利用率的应用
-
原因:更细粒度地管理内存,减少内存碎片。
-
示例:嵌入式系统、实时操作系统。
-
-
多任务并发环境
-
原因:提高内存分配效率,减少任务间干扰。
-
示例:多用户操作系统、移动设备操作系统。
-
-
高实时性要求的应用
-
原因:减少内存分配和释放开销,确保及时响应。
-
示例:工业控制系统、实时音视频处理。
-
结论
-
页越大越好:适用于大数据处理、高吞吐量I/O操作、虚拟化。
-
页越小越好:适用于高内存利用率、多任务并发、高实时性要求的场景。
操作系统通常在这两者之间找到平衡点,如使用4KB的默认页大小,同时支持大页以优化特定应用性能。
文件管理
---文件系统---
文件、目录概念
文件的概念
-
定义:记录在外存上的具有名称的相关信息集合。
-
属性:名称、标识符、类型、位置、保护、时间、日期等。
目录的概念
-
定义:由文件说明索引组成的用于文件检索的特殊文件。
-
内容:包含文件的属性、位置、所有权等信息。
目录结构的概念
目录结构是组织文件和目录的一种层次结构,帮助操作系统高效管理和访问文件。
目录结构类型&优缺点
目录结构类型及优缺点
-
单层结构目录
-
优点:简单、易实现、搜索高效。
-
缺点:命名冲突、无法区分用户、文件共享困难。
-
-
两级结构目录
-
优点:解决命名冲突、用户独立目录、搜索高效。
-
缺点:文件共享困难、多次备份问题。
-
-
树状结构目录
-
优点:层次清晰、易于管理、搜索高效。
-
缺点:多用户文件共享问题。
-
-
无环图目录
-
优点:方便文件共享。
-
缺点:多个绝对路径、悬空指针问题。
-
-
通用图目录
-
优点:解决共享问题。
-
缺点:重复遍历和自我引用问题。
-
优点
-
搜索高效:快速找到所需文件。
-
易于管理:层次化结构便于组织和管理。
-
共享文件:方便文件共享。
缺点
-
命名冲突:单层和两级目录容易出现。
-
共享问题:树状目录在多用户环境中对共享支持不足。
-
复杂性:复杂结构需更复杂的管理和维护。
保护机制总结(内存、I/O、文件系统等)
内存保护
-
目的:防止非法访问和修改内存中的数据,确保系统稳定性和安全性。
-
措施:
-
基址寄存器和限长寄存器:通过基址寄存器和限长寄存器来控制进程访问的内存范围。
-
特权指令:修改基址寄存器和限长寄存器的指令为特权指令,只能由操作系统执行。
-
I/O 保护
-
目的:防止用户进程直接操作I/O设备,避免系统资源被非法使用或破坏。
-
措施:
-
特权指令:将所有I/O指令设为特权指令,用户进程必须通过系统调用来执行I/O操作。
-
I/O控制:操作系统通过I/O控制器管理设备,用户程序无法直接访问硬件。
-
文件系统保护
-
目的:保护文件和目录不被非法访问、修改或删除,确保数据安全和一致性。
-
措施:
-
访问控制:文件所有者可以通过设置访问权限(如读、写、执行)来控制不同用户对文件的操作。
-
权限管理:采用如UNIX的权限管理机制,对文件和目录的所有者、所属组和其他用户设置不同的权限。
-
符号链接:当实际文件被删除时,链接保留,当用户通过链接访问文件时通知用户链接已失效 。
-
CPU保护
-
目的:确保操作系统对CPU的控制,防止用户进程占用CPU资源不释放。
-
措施:
-
定时器中断:使用定时器在给定时间后中断CPU操作,防止进程陷入死循环。
-
特权指令:设置定时器的操作为特权指令,确保只有操作系统能修改定时器 。
-
总结
内存、I/O和文件系统等资源的保护是操作系统的重要职责,通过使用特权指令、访问控制和定时器等机制,确保系统资源不被非法访问和操作,维护系统的稳定性和安全性。文件系统通过访问权限和符号链接等机制来管理文件的访问和共享,防止数据丢失和破坏 。
**open read文件 一个图
1.open()操作: 用户给 open()传入一个文件的逻辑路径名,这时先将该文件系统的目录结构加载进内存,根据文件名,操作系统会首先对系统范围内的打开文件表进行搜索(节省时间)。 如果该文件已经被其他进程打开了,则直接将该进程的打开文件表中的指针指向系统范围打开文件表的这一项,同时,系统打开文件表该文件引用计数加 1。
如果该文件在系统范围文件表中不存在,说明该文件第一次打开,则对该文件系统的目录表进行搜索,依次查找到叶结点,叶结点包含了一个该文件控制节点(inode)号,即控制节点的物理位置指针,将这个指针返回给用户,同时在系统范围打开文件表中新注册一行这个文件的信息,将该进程的打开文件表中指针指向这条新信息,open()操作的任务就完成了。
(2) read()操作 通过 open()操作返回的该文件的索引节点号从进程的打开文件表中的指针找到系统的打开文件表中该文件的 inode(FCB)物理位置指针,将该 FCB 读入内存,通过FCB 中文件存储类型和存储地址的信息算出数据块的存储地址,将数据块读入即可完成 read()操作。
open() 操作流程
-
用户调用 open(),传入文件路径名。
-
加载目录结构到内存。
-
检查系统范围内的打开文件表
:
-
文件已打开:增加引用计数,并更新进程的打开文件表。
-
文件未打开:查找目录表,获取 inode,注册到系统范围的打开文件表,并更新进程的打开文件表。
-
read() 操作流程
-
通过 open() 返回的 inode 号查找进程的打开文件表。
-
找到系统打开文件表中的 inode(FCB)。
-
读取 FCB,计算并读入数据块。
****文件物理空间的分配方法
文件的物理空间分配是操作系统管理文件系统的一项重要功能,其目的是高效地利用磁盘空间并确保文件的快速访问。根据《操作系统第七版重点总结》和《04操作系统山软智库知识见解_V1.0》PDF中的内容,文件物理空间分配的方法主要有以下几种:
1. 连续分配(Contiguous Allocation)
特点:
-
文件占用一组连续的磁盘块。
优点:
-
顺序访问性能好,因为文件的所有块在物理上是连续的。适合文件内容不进行变动的情况
-
实现简单,文件目录只需记录文件的起始块号和长度。
缺点:
-
磁盘碎片问题严重,需要定期进行碎片整理。
-
文件大小难以动态扩展,需要预先分配足够大的空间。
2. 链接分配(Linked Allocation)
特点:
-
文件的每个块包含指向下一个块的指针,文件的块不需要连续存储。
优点:
-
没有外部碎片问题,可以动态分配文件所需的空间。
-
文件大小可以动态扩展,只需在末尾添加新的块。
缺点:
-
顺序访问速度较慢,因为每次读取都需要访问指针。
-
可靠性差,若某块的指针损坏,会导致文件部分丢失。
加入文件分配表(File Allocation Table)的链接分配改进版
每个卷的开始部分用来存储该卷的 FAT,每块在该表中都有一项,该表可以通过块号码进行索引,FAT 使用跟链表相似,目录条目含有文件首块的块号,根据块号索引的 FAT 条目包含文件下一块的块号,这条链一直继续直到最后一块,该块对应的FAT 条目的值为文件的结束值,该项存一个特殊的结尾符表示文件的结束。
优点: 通过一下 IO 一次性读入 FAT 表进入内存,就可实现对文件任意位置的随机访问(链表移动工作放在了内存中对 FAT 表项的移动) 问题: 如果不采用缓存(Cache)将 FAT 表读入内存,会导致每次访问都要先访问 FAT表,导致访问时间的浪费。
3. 索引分配(Indexed Allocation)
特点:
-
为每个文件建立一个索引块,索引块包含文件所有块的指针,上面存放着磁盘块地址的数组。
索引块的第 i个条目指向了文件的第 i 个块
优点:
-
支持随机访问,访问任意块的时间复杂度为O(1)。
-
没有外部碎片问题,可以动态分配空间。
-
可扩展,文件不需要提前声明大小
缺点:
-
需要额外的磁盘块来存储索引,增加了存储开销。
-
索引块的大小限制了文件的最大大小,如果文件非常大,可能需要多级索引。
综合分析
每种分配方法都有其优缺点,适用于不同的场景:
-
连续分配:适用于文件大小固定且较少变化的场景,如数据库文件。
-
链接分配:适用于文件大小变化较大且顺序访问较多的场景,如日志文件。
-
索引分配:适用于需要频繁随机访问的场景,如程序代码和文档。
通过合理选择和组合不同的分配方法,操作系统可以高效管理磁盘空间,满足不同应用的需求。
空闲空间管理(了解 位向量链表--了解)
空闲空间管理
空闲空间管理是文件系统管理中一个重要的部分,主要目的是高效地管理和分配磁盘中的空闲空间。常用的空闲空间管理方法有位向量和链表。
1. 位向量(Bit Vector)
定义:
-
位向量使用一个比特数组来表示磁盘块的使用情况,每一位表示一个磁盘块,0表示空闲,1表示已使用。
优点:
-
简单直观:容易实现和理解。
-
快速访问:可以通过简单的位运算快速找到空闲块。
缺点:
-
空间开销:位向量本身需要占用一定的存储空间,尤其是在大容量磁盘上。
-
扫描时间:在寻找连续空闲块时,可能需要扫描整个位向量,时间开销较大。
示例:
-
假设有一个磁盘包含16个块,位向量如下:
0011100000111000
表示块2、3、4、10、11、12被占用,其余为空闲。
2. 链表(Linked List)
定义:
-
链表使用链表结构将所有空闲块连接起来,每个空闲块包含一个指向下一个空闲块的指针。
优点:
-
节省空间:不需要额外的位向量空间,直接使用磁盘块的指针。
-
灵活性:可以很容易地分配和释放块,链表自动更新。
缺点:
-
访问速度较慢:在查找特定数量的连续空闲块时,可能需要遍历整个链表。
-
管理复杂性:维护链表的插入和删除操作较为复杂。
示例:
-
假设有以下空闲块链表:
[0] -> [5] -> [6] -> [13] -> [14]
表示块0、5、6、13、14为空闲块。
总结
位向量和链表的比较
-
位向量:
-
优点:简单直观,快速访问。
-
缺点:空间开销大,扫描时间长。
-
-
链表:
-
优点:节省空间,灵活性高。
-
缺点:访问速度较慢,管理复杂。
-
通过选择合适的空闲空间管理方法,可以优化磁盘空间的利用,提高文件系统的效率和性能
---大容量---
**磁盘结构
磁盘结构 现代磁盘驱动器可以看做一个一维逻辑块的数组,逻辑块是最小的传输单位,一维逻辑块数组按顺序映射到磁盘的扇区,理论上能将逻辑块号转换为磁盘内的柱面号、磁道号和扇区号。但是事实上执行这种转换并不容易,因为: ①绝大多数磁盘都有一些缺陷扇区,映射必须要用磁盘上其他空闲扇区替代 ②磁盘是圆的,磁道离中心越远长度越长。为此有两种解决方式,一种是增加外部扇区数并且随着磁头外移驱动器也会增加速度;另一种方式时降低外道的磁道密度
****磁盘调度和raid结构出一个题
磁盘带宽:所传递的总的字节数除以从服务请求开始到最后传递结束的总时间
当一个进程需要对磁盘进行 I/O 操作时,它就会向操作系统发出一个系统调用,如果所需的磁盘驱动器和控制器忙,新的服务请求就会被加到该磁盘驱动器的待处理请求队列上。对于如何选择处理请求,操作系统有多个调度算法可供使用。
下面以一个请求顺序为例讨论磁盘的各种调度算法。
磁盘队列对 I/O 各柱面上的请求顺序为:98,183,37,122,14,124,65,磁头开始于位置 53,假定磁盘的最外道号为 199,最内道号为 0
****raid结构和磁盘调度出一个题(两方面好处 这两方面优点如何实现)
RAID的概念及其好处
RAID的概念
RAID(Redundant Array of Independent Disks,独立磁盘冗余阵列)是一种将多个物理硬盘组合成一个逻辑单元,以提高数据存储性能和提供容错能力的技术。RAID技术通过数据分条(striping)、镜像(mirroring)和奇偶校验(parity)等方法在多个磁盘上分布数据,实现数据冗余和提升存储性能。
RAID的两方面好处及其实现
1. 通过冗余改善可靠性
实现方式:
-
引入冗余:存储额外信息以修复磁盘出错时的损坏数据。
-
镜像技术(Mirroring):最简单的冗余方式是复制每个磁盘的数据,但这种方法成本较高。
具体实现:
-
磁盘镜像:每个数据块在两个磁盘上都有副本。当一个磁盘发生故障时,系统可以从另一个磁盘读取数据,保证数据的完整性和可用性。
2. 通过并行处理改善性能
实现方式:
-
并行处理:通过数据分散到多个磁盘上,多个磁盘可以同时处理读写操作,提高数据传输率。
具体实现:
-
位级分散(Bit-level Striping):
-
将每个字节的各个位分散到多个磁盘上。例如,在8个磁盘上,每个磁盘存储一个位,这样传输率提高了8倍。
-
-
块级分散(Block-level Striping):
-
将文件的块分散到多个磁盘上。每次读块操作只访问一个磁盘,可以同时进行多个读操作,提高读传输速度。写操作时,数据和奇偶校验可以并行写入,提高写传输速度。
-
综合优势的实现
RAID技术结合了数据并行处理和数据冗余技术,提供了高性能和高可靠性:
-
数据并行存取:
-
数据按位级或块级分散写入到多个磁盘上,使得多个磁盘可以同时进行读写操作,提高系统性能。
-
-
数据冗余校验:
-
使用磁盘镜像或其他校验技术(如CRC、Hamming码等)提供数据冗余,当一个或多个磁盘发生故障时,可以通过冗余信息恢复数据,提升系统可靠性。
-
RAID级别
常见的RAID级别包括:
-
RAID 0:数据分条,没有冗余,性能提升显著,但不提供容错能力。
-
RAID 1:数据镜像,提供高冗余和容错能力,性能提升有限。
-
RAID 5:数据分条和奇偶校验,提供较好的性能和冗余平衡。
-
RAID 6:双重奇偶校验,允许两个磁盘同时故障,提供更高的容错能力。
-
RAID 10:组合RAID 0和RAID 1的优点,提供高性能和高冗余。
通过使用RAID技术,企业和个人用户可以在存储系统中实现数据保护、提高性能和增加存储容量,满足多样化的存储需求。
IO管理
轮询,轮转,DMA机制 的优缺点以及适用情况
轮询(Polling)
优点:
-
实现简单:轮询机制简单易实现,无需复杂的硬件支持。
-
控制方便:CPU完全控制I/O设备,适用于简单的I/O操作。
缺点:
-
低效:CPU不断循环检查I/O设备状态,浪费大量时间。
-
忙等待:CPU在等待I/O设备准备好时无法执行其他任务。
适用情况:
-
适用于简单、低速的I/O设备,如键盘、鼠标等。
-
在实时性要求不高的场景下使用。
轮转(Round Robin)
优点:
-
公平分配CPU时间:每个进程轮流获得CPU时间,避免某个进程长期占用CPU。
-
响应速度快:适用于多任务环境,能够快速响应用户操作。
缺点:
-
处理开销大:频繁的上下文切换增加了系统开销。
-
时间片选择难:时间片过长或过短都会影响系统性能。
适用情况:
-
适用于多任务操作系统,如Windows、Linux。
-
在交互式系统中使用,如终端、桌面环境。
DMA机制(Direct Memory Access)
优点:
-
高效:DMA控制器直接在内存和I/O设备之间传输数据,无需CPU干预,提高传输效率。(1次)
-
减少CPU负担:CPU在数据传输过程中可以执行其他任务,提高系统整体性能。
缺点:
-
复杂性高:需要专门的DMA控制器和复杂的硬件支持。
-
设备冲突:多个DMA设备同时请求时可能导致冲突,需要有效的仲裁机制。
适用情况:
-
适用于高速数据传输设备,如磁盘驱动器、网络接口。
-
在需要大量数据传输的场景下使用,如多媒体应用、数据采集系统。
这些回答基于操作系统的基本原理,具体内容可参考相关教材和资料。
中断在I/O中的几个问题以及解决方法
概念: 中断是一种机制,允许I/O设备在完成操作或需要处理时通知CPU,使CPU可以在I/O操作完成前执行其他任务,提高系统效率。
使用流程:
-
I/O请求:
-
CPU发出I/O请求后,不必等待I/O操作完成,继续执行其他任务。
-
-
I/O操作进行中:
-
I/O设备独立完成数据传输。
-
-
中断信号:
-
I/O操作完成后,I/O设备发送中断信号给CPU。
-
-
中断处理:
-
CPU接收到中断信号后,暂停当前任务,执行中断服务例程(ISR)处理I/O操作结果。
-
-
恢复任务:
-
中断处理完成后,CPU恢复之前被中断的任务。
-
中断中的几个问题和解决方法
1. 中断向量
问题:
-
当中断发生时,系统需要知道去哪个地址获取中断服务例程(ISR)。
解决方法:
-
中断向量表:系统维护一个中断向量表,每个中断类型对应一个中断向量(指向ISR的指针)。当中断发生时,CPU使用中断类型作为索引查找中断向量表,获取ISR的地址。
2. 可屏蔽中断和不可屏蔽中断
问题:
-
某些中断可以被暂时忽略或延迟处理,而其他中断需要立即处理。
解决方法:
-
可屏蔽中断(Maskable Interrupts, MI):
-
可以通过设置中断屏蔽位来屏蔽这些中断。例如,CPU忙于处理高优先级任务时可以屏蔽低优先级中断。
-
适用场景:一般用于非紧急任务,如定时器中断、键盘中断等。
-
-
不可屏蔽中断(Non-Maskable Interrupts, NMI):
-
无法被屏蔽,必须立即处理。这类中断通常用于紧急情况,如硬件故障。
-
适用场景:紧急任务,如电源故障检测、硬件故障等。
-
3. 中断优先级
问题:
-
多个中断源同时发生时,系统需要确定哪个中断优先处理。
解决方法:
-
中断优先级机制:
-
为每个中断分配优先级,当多个中断同时发生时,CPU根据优先级顺序处理中断。
-
使用中断控制器来管理和判定中断优先级。
-
4. 中断处理的嵌套
问题:
-
当前中断处理过程中发生了新的中断,如何处理?
解决方法:
-
中断嵌套:
-
允许高优先级中断打断低优先级中断的处理。CPU保存当前中断的上下文,处理高优先级中断,完成后再恢复低优先级中断的处理。
-
使用堆栈保存和恢复中断处理的上下文。
-
5. 中断处理的延迟
问题:
-
过多的中断会导致系统频繁上下文切换,增加处理延迟。
解决方法:
-
中断批处理:
-
将多个低优先级中断合并处理,减少频繁的上下文切换。
-
-
中断屏蔽和恢复:
-
在关键代码段屏蔽中断,完成后立即恢复中断,使关键代码段不被打断。
-
Cache buffering的三个用途&spoling假脱机
Cache Buffering的三个用途
-
数据暂存:
-
用途:在数据被最终写入到存储设备之前,首先被写入缓存。这可以减少直接写入磁盘的次数,减少I/O操作,提高系统性能。
-
优点:提高写操作的效率,减少磁盘的写入次数,从而延长磁盘寿命。
-
-
数据预取:
-
用途:在需要数据之前,将数据从慢速存储设备读取到高速缓存中。这样,当程序需要数据时,可以直接从高速缓存中读取,而不是等待慢速存储设备读取数据。
-
优点:提高读操作的效率,减少等待时间,提升系统整体性能。
-
-
数据共享:
-
用途:允许多个进程共享缓存中的数据,避免重复读取相同的数据。这在多任务操作系统中尤为重要,因为多个进程可能需要访问相同的数据。
-
优点:减少重复I/O操作,节省时间,提高系统效率。
-
Spooling(假脱机)
定义:
-
Spooling(Simultaneous Peripheral Operations Online)是一种将数据临时存储在磁盘等中间存储设备中的技术,以便设备能够按需访问这些数据。这种方法通常用于管理和优化外设(如打印机)的使用。
用途:
-
作业管理:
-
允许系统将多个作业排队,按照顺序执行,提高设备利用率和系统吞吐量。
-
-
数据缓冲:
-
将数据临时存储在磁盘上,设备可以在空闲时访问和处理数据,而不需要等待数据的生成或传输。
-
-
资源共享:
-
多个用户或进程可以共享同一个外设,如打印机,避免冲突,提高资源利用效率。
-
通过Cache Buffering和Spooling,操作系统可以显著提高I/O操作的效率和系统的整体性能。这些技术在实际系统中得到了广泛应用,特别是在高性能计算和多任务处理环境中。