操作系统笔记(本科必修课)

2023-05-16

1 操作系统概论

1.1 定义

操作系统是计算机系统中的一个系统软件,是一些程序模块的集合。能以尽量有效、合理的方式组织和管理计算机的软、硬件资源,合理的组织计算机的工作流程,控制程序的执行并向用户提供各种服务功能,使得用户能够灵活、方便、有效的使用计算机,使整个计算机系统能高效运行。是计算机与用户之间的接口

1.2 发展历程

1.2.1 无OS的计算机系统

  • 单用户独占全机

  • CPU等待人工操作

    • 人工负责输入输出

    • 人工负责计算机的调度

    • 人工负责编排作业的运行顺序

1.2.2 单道批处理

以常驻内存的监控程序代替人工调度和作业编排。

  • 早期联机批处理

    作业的输入、计算和输出都在CPU控制下进行,CPU利用率低

  • 早期脱机批处理

    小型卫星机控制外部设备的输入和输出

  • 优点

    1. 系统自动化程度高、吞吐量大、资源利用率高

    2. 减少CPU空闲时间

    3. 提高I/O速度

  • 缺点

    1. CPU与外设串行

    2. 作业周转时间长,用户无法控制作业

1.2.3 多道批处理

引入原因:提高CPU利用率

特点:

  • 内存多道

  • 宏观并行

    • 程序之间

    • 设备与设备之间

    • CPU与设备之间

  • 微观串行:在CPU上交叉运行

性能指标:

  • 资源利用率:给定时间内系统中某一资源(存储器、CPU、外设等)实际使用时间所占比率

  • 吞吐量:单位时间内系统所处理的信息量,通常以每小时或每天所处理的作业个数进行度量。

  • 周转时间:作业完成时间-到达时间

  • 平均周转时间:多个作业的周转时间的平均值。

典型系统:

IBM OS/360:首次将操作系统与计算机相分离,从专用走向通用的操作系统。

1.2.4 分时系统

CPU与通道、通道与通道、通道与设备并行操作。目标是对用户请求的快速响应。

响应时间:从用户发出终端命令到系统响应并开始进行应答所需的时间,T=nq,n是同时上机的用户数,q是时间片。

特点:

同时性、独立性、交互性、及时性

典型系统:

  • CTSS

  • MULTICS,分时、文件系统、动态链接-->Unix-->Linux

  • DOS/Windows

  • macOS

1.2.5 实时系统

以数据或信息作为处理对象。是专用系统,主要用于实时过程控制和实时信息处理。

应用需求:

  • 实时控制

  • 实时信息处理

类型:

  • 实时控制系统/实时信息处理系统

  • 硬实时

    系统的所有可能的延迟是一定的,对关键的任务,必须在指定时间范围内完成

  • 软实时

    可以允许任务没有在规定时间内完成

特点:

实时性、可靠性、确定性

1.2.6 分布式系统

A distributed system is a collection of independent computers appears to its users as a single coherent system.

A distributed system is the one in which hardware or software components located at networked computers communicate and coordinate their actions only by passing messages.

  • component: autonomous

  • user: a single system

1.2.7 其他操作系统

嵌入式系统

以应用为中心,以计算机技术为基础,软硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。

运行的几乎都是实时操作系统。

特点:

  • 软件固化存储

  • 高质量、高可靠性、高实时性

典型系统:

Linux、FreeRTOS

智能移动终端

  • 有限的计算能力上提供丰富的用户体验

  • 有限的供电能力上改善系统的能源效率

  • 在存储大量用户敏感信息的场景下保证用户信息的隐私和安全

典型系统:

Android、iOS

1.3 特性

  • 并发性

    并发:程序在同一时间间隔执行。

    并行:程序在同一时刻执行。多核才能做到

  • 共享性互斥共享

  • 虚拟性

    • 通过某种技术把资源的一个物理实体变为若干个逻辑实体

    • CPU分时、虚拟存储器、虚拟设备、虚拟机等

  • 异步性

    • 有限资源共享使并发进程间产生制约关系,导致进程执行“走走停停”

允许程序并发活动的系统称为多道程序系统多处理系统

1.4 作用、功能与服务

1.4.1 作用

  • 对用户:提供操作计算机的接口

  • 对系统设计者:更方便地管理资源

1.4.2 功能

  • 处理机管理

    进程控制、进程同步、进程通信、进程调度

  • 内存管理

    内存分配、内存保护、地址映射、内存扩充

  • 文件管理

    文件存储空间的管理、目录管理、文件的读写管理和保护

  • 设备管理

    缓冲管理、设备分配

1.4.3 服务

  • 用户接口

    • 命令行接口(操作接口)

      • 命令行界面

      • 图形用户界面GUI

      • 触屏界面

    • 程序级接口(编程接口)

      常以系统调用(system call)的形式出现。系统调用包括:进程控制、文件管理、设备管理、其他服务。以API的形式提供。

      • 两类API:Win32 API、POSIX API

      • 六类系统调用

        1. 进程控制

        2. 文件管理

        3. 设备管理

        4. 信息维护

        5. 通信

        6. 保护

  • 其他服务

    执行程序、I/O操作、文件系统服务、通信服务、错误检测和处理、资源分配、记账(统计各个用户程序占有的系统资源情况)、保护

1.5 运行方式

双重模式操作

  • 内核模式:OS内核程序

    • 允许执行全部指令

    • 允许访问所有的寄存器和缓冲区

  • 用户模式:用户程序、系统外层应用程序

    • 只能执行非特权指令

    • 只能访问特定的寄存器和存储器

特权指令

  • 能引起损害的机器指令,如:I/O控制,定时器管理,中断管理

  • 关系系统全局的指令,包括:存取和操作CPU状态,启动外部设备,设置时钟时间,关中断,清主存,修改存储器管理寄存器,改变用户方式到核心方式和停机指令。

模式切换

  • 用户模式→内核模式:中断、异常、系统调用

  • 内核模式→用户模式:

    • 完成中断或异常的处理

    • 新进程或线程启动

    • 进程调度选择执行新的进程

    • 操作系统向进程发送信号

1.6 内核架构

1.6.1 简要结构

应用程序和操作系统在同一个地址空间。把操作系统按功能划分为若干个具有一定独立性和大小的模块和子模块,各模块间通过接口实现交互。

典型系统:MSDOS

优点:

  • 提高了OS设计的正确性、可理解性和可维护性

  • 增强了OS的适应性

  • 加速了OS的开发过程

缺点:

  • 系统结构不清晰

  • 系统可靠性降低

  • 未能区分共享资源和独占资源

1.6.2 宏内核

Monolithic Kernel, Macrokernel

操作系统内核的所有模块均运行在内核态(单内核),具备直接操作硬件的能力。模块之间可以直接调用,不进行模式切换。

优点:

系统内核模块之间的通信开销小,性能较好

缺点:

  • 系统复杂,不易维护

  • 易导致DOS系统病毒泛滥,进而引起系统崩溃

典型系统:

Unix、Linux、早期的Windows、FreeBSD

1.6.3 微内核

Microkernel

操作系统内核只保留最基本的功能,如进程/线程调度、消息传递、存储器管理和设备驱动等,其他功能包括各种API、文件系统和网络等放在用户层以服务的形式实现。

微内核的主要功能是提供client程序和server服务器之间的以消息传递方式的通信设施。

优点:

  • 便于扩充操作系统的功能

  • 便于把系统从一种硬件平台移植到另一种平台上

缺点:

增加了系统开销,使系统性能降低

典型系统:

QNX、Minix、seL4

1.6.4 外核

Exokernel

1.6.5 多内核

Multikernel

1.6.6 混合内核

Hybrid Kernel

为了更好地解决性能、安全性、可用性和可扩展性等问题而采用的。

典型系统

Windows NT之后的操作系统(Windows 8、Windows 10等),Mac OS X

1.7 题目

分时系统的特点:同时性、独立性、交互性、及时性

实时系统的特点:实时性、可靠性、确定性

操作系统的特性:并发性、共享性、虚拟性、异步性

由用户态切换到内核态发生在:中断、异常、系统调用

进程的特点:动态性、独立性、并发性、结构性、异步性

进程和程序的本质区别:动态和静态特征

可能在用户态发生的:命令解释、外部中断、系统调用

汽车电子系统中使用的是嵌入式操作系统

× 操作系统能执行的是特权指令集合。

与交互式系统相关的是:响应时间、时间片

fork()函数属于进程控制类

只能在内核态下运行的指令有:禁止中断指令、I/O指令、设置时钟

用户向操作系统提出服务请求有两种方式:终端命令、系统调用

必须包含在操作系统内核中的是:中断处理

执行系统调用的过程:传递系统调用参数-->执行陷入指令-->执行相应的服务程序-->返回用户态

命令解释程序在用户态执行。

系统调用的功能由内核函数实现。

单处理机系统中,可以并行的是:处理机与设备、处理机与通道、设备与设备

操作系统提供给用户的接口是系统调用

2 进程、线程、调度与通信

2.1 进程

进程的引入:描述程序的执行过程

运行结果的封闭性:程序在运行时独占全机资源。

运行结果的可再现性:只要初始条件相同,程序的执行结果总是相同,不受其他条件影响。

2.1.1 定义

  • 是程序的一次执行过程

  • 是程序在一个数据集合上顺序执行时发生的活动

  • 是系统进行资源分配和调度的一个独立单位

进程程序
动态性:状态转换静态
独立性:资源分配、处理机调度非独立
并发性不可并发
异步性
结构:进程控制块

2.1.2 进程描述

进程控制块

  • 进程标识数(标识符),进程的唯一标识

  • 进程的状态

  • 调度和存储器管理信息

  • 进程使用的资源信息

  • CPU现场保护区

    • 程序计数器

    • 程序状态字

    • 通用寄存器

    • 堆栈指针

  • 记账信息

  • 进程之间的家族关系

  • 进程的链接指针

进程的状态

  • 创建态 Created

  • 终止态 Terminated

  • 就绪态 Ready

  • 运行态 Running

  • 阻塞等待态 Blocking or Waiting

     

阻塞态不能直接变到运行态。

2.1.3 进程的控制

原语:完成特定功能,执行过程不能中断

  • 创建原语

    主要任务是建立一个控制块。执行过程:

    1. 找到一个空闲的PCB

    2. 分配内存,调入主存

    3. 把参数:进程名、进程优先级等填入PCB结构中

    4. 把进程置位为就绪状态,插入就绪队列中

  • 撤消原语

    一个进程已完成指定任务,或由于故障不能继续运行时,需要撤销进程控制块,使其从系统中消亡。同时将其创建的各个子孙程序也全部撤销。

  • 阻塞原语

    处于运行态的进程在等待事件时,进程自己执行阻塞原语,使自己变为阻塞态。

    功能:

    • 中断CPU,将其运行现场保存在其CPU现场保护区

    • 状态置为阻塞态,插入相应事件的等待队列中

    • 最后转处理机调度

  • 唤醒原语

    将程序由阻塞态置为就绪态

  • 挂起原语

  • 解挂(激活)原语

2.2 线程

在引入线程的操作系统中,把线程作为处理机调度的基本对象,而进程只作为除CPU之外的系统资源的分配对象。

引入目的

  • 提高响应速度

  • 资源共享:共享进程资源

  • 降低系统开销

特点

  • 独立调度

  • 并发/并行

  • 动态性

  • 结构性

    • 线程状态

    • 执行堆栈

    • 程序计数器

    • 寄存器集

同一个进程的不同线程通过共享进程的存储空间进行信息交换。

一般把线程叫做轻型进程;传统的进程叫做重型进程,是拥有一个线程的进程。

2.2.1 线程控制块

  • 唯一标识符

  • 表示处理机状态和运行现场的一组寄存器

  • 两个堆栈,分别用于用户态和核心态调用时进行参数传递

  • 独立的程序计数器

  • 关联的进程和线程指针

2.2.2 系统对线程的支持

用户级线程

有关线程的所有管理工作都由用户程序通过调用用户态运行的线程库完成,系统内核不知道线程的存在。

不要求内核支持线程,内核仍以进程为单位进行调度。

任何一个用户级线程的阻塞,都将引起整个进程的阻塞。

多对一的模型

核心级线程

有关线程的所有管理工作都由系统内核完成。

在一个多处理机系统中,可以将同一进程的不同线程调度到不同的处理机上。

  • 缺点:创建、管理的开销大

  • 优点:数据结构和堆栈小,线程切换快

一对一的模型

两级组合

多个用户级线程可以对应等量或少量的核心级线程。

多对多的模型

2.3 调度

调度级别

  • 高级调度,也称作业调度

  • 低级调度,也称进程调度

  • 交换调度

调度方式

  • 非抢先(非剥夺)方式:一旦把CPU分配给某一进程便让它一直运行下去,直到进程完成或发生事件不能运行时,才将CPU分给其他进程。

  • 抢先(剥夺)方式:一个进程正在执行时,系统可以基于某种策略剥夺CPU给其他进程。

调度时机:

  • 现行进程完成执行或由于某种错误而中止运行

  • 正在执行的进程提出I/O请求,等待I/O完成

  • 分时系统中,按照时间片轮转,分给进程的时间片用完

  • 基于优先级调度,有更高优先级进程变为就绪

  • 进程执行了某种原语操作,如阻塞原语或唤醒原语,都可能引起进程调度

2.3.1 单处理器调度

2.3.1.1 先来先服务 FCFS

系统维护一个FIFO队列,按照进程到达就绪队列的先后次序顺序调度运行。

  • 优点

    节省机器时间,运行效率高

  • 缺点

    容易被大作业进程垄断,使平均等待时间延长

2.3.1.2 短作业优先 SJF

可以使用剥夺(最短剩余时间优先)、非剥夺的方式。最优算法

每次调度时总是选取运行时间最短的进程运行。

  • 优点

    • 对运行时间时间短的进程有利

    • 进程的平均等待时间和周转时间最佳

  • 缺点

    • 可能导致长进程没有时间运行,出现饿死现象

    • 进程执行时间难以确认

2.3.1.3 高响应比优先 HRN

可以避免饿死现象。

响应比定义为:

R_q=(作业等待时间+作业估计运行时间)/(作业估计运行时间)=1+作业等待时间 / 作业估计运行时间
  • 缺点

    需要经常计算各个作业的响应比,系统开销比较大。

2.3.1.4 优先级调度 PS

是最常用的一种进程调度算法。

系统总是把CPU分配给就绪队列中优先级最高的进程。

确定优先级的方法:

  • 静态优先级法

    • 优先级在进程创建时确定的。系统进程的优先级通常较高。用户进程中,申请资源量少的有较高优先级。

    • 不能动态反映进程特点;低优先级的长进程容易饿死。

  • 动态优先级法

    • 随着进程执行时间的变化,优先级不断进行动态调整。

    • 动态计算优先级,系统需要付出一定开销。

通常根据进程占用CPU时间的长短或等待CPU时间的长短动态调整。

2.3.1.5 轮转法 RR

通常用在分时系统中。

时间片长短的确定:既要保证系统各个用户进程及时地得到响应,又不要由于时间片太短而增加调度开销,降低系统效率。

2.3.1.6 多级反馈队列轮转法 MFQ

设置多个就绪队列,前台队列采用RR,后台队列采用FCFS调度。系统在调度时,总是先调度优先级高的队列,仅当该队列为空时,才调度次高优先级队列。

  • 前台进程的优先级都高于后台进程

  • 高优先级队列进程的时间片短,低优先级队列进程的时间片长

  • 通常刚创建的进程和因请求I/O未用完时间片的进程排在最高优先级队列

  • 优点:

    既能使分时用户作业得到满意的响应,又能使批处理用户的作业获得较合理的周转时间。

2.3.2 周期性硬实时系统

2.3.2.1 最早截止时间调度 EDF

截止时间越早,优先级越高。

2.3.2.2 最小松弛度优先 LLF

松弛度的计算:


松弛度=程序截止时间-已运行时间-当前时间

多个程序在就绪队列中时,选取松弛度最小的运行;松弛度为0的进程抢占当前运行的进程。

2.3.2.3 单调速率调度 RMS

基于任务的周期长短赋予优先级,周期越短,优先级越高。


任务周期=下一任务到达时间-该任务到达时间

任务速度=1 / 任务周期


CPU利用率=任务执行时间 / 任务周期
 

2.3.2 多处理器调度

对SMP系统,需要保持多个处理器的负载均衡,以提高多个处理器的利用率;会尽量使一个进程保持在同一个处理器上运行,以提高缓存内数据的命中率,即处理器亲和性。

处理器亲和性:一个进程对其原本运行的处理器具有亲和性。

  • 软亲和:进程可以迁移到其他处理器

  • 硬亲和:程序员可以通过系统调用来设置亲和处理器

协同调度

将一个工作量较大的任务切分成多个子任务,每个子任务由不同CPU核心完成。尽可能让一组任务并行执行,避免调度器同时调度有依赖关系的两组任务

群组调度策略

将关联任务设置为一组,以组为单位调度任务在多个CPU核心上执行

缺点:无关联任务之间的相互等待可能造成CPU资源的浪费

两级调度

  • 全局调度器:决定任务被哪个CPU核心执行

  • 本地调度器:任务一直被该核心调度,不会发生迁移

2.4 进程通信

进程间的关系:

  1. 资源共享引起的互斥关系——直接的制约

  2. 协作完成同一个任务引起的同步关系——间接的制约

  3. 进程之间的前序关系

进程通信的两种方式:

  • 共享内存

  • 消息传递

根据进程间交换的信息量大小和效率高低,可以分为:

  • 低级通信:主要用于进程之间的同步、互斥、终止、挂起等控制信息的传递

  • 高级通信:主要用于进程间数据块的交换和共享,常见的方式有管道、消息队列、共享内存等

2.4.1 临界资源

临界资源是一次仅允许一个进程使用的系统中的一些共享资源。包括:

  • 慢速的硬设备,如打印机等

  • 软件资源,如:共享变量、共享文件、各种队列等

临界区:并发进程访问临界资源的那些必须互斥执行的程序段。

并发进程进入临界区需要遵循四个准则:

  1. 互斥使用:不能同时有两个进程在它们的临界区内执行

  2. 有空让进:在临界区之外运行的进程不可以阻止其他的进程进入临界区

  3. 有限等待:不应该使要进入临界区的进程无限期地等待在临界区之外

  4. 让权等待:等待进入临界区的进程,应释放处理机后阻塞等待

每个进程进入临界区之前需要执行enter section代码段,请求许可权;退出执行时,执行exit section代码段释放对临界区操作的使用权。这些代码段的执行是不可中断的,从而保证并发进程互斥地进入临界区。

do{
	...前序代码
	Enter Section
	{Critical Section Code}
	Exit section
	Reminder Section
	...后序代码
}while(1);

解决进程互斥的方法:

  • 硬件方法

    • 内存屏障——互斥锁

    • 硬件指令

      • 关中断

      • Test & Set

      • Compare & Swap

    • 原子变量

  • 软件方法:Peterson算法

硬件方法不能实现让权等待;Peterson算法只满足有限等待。

关中断

当一个进程正在临界区执行时,关闭所有的中断。

原理:CPU只有在发生时钟中断或其他中断时才会进行进程切换。

实现:

  1. 关中断(disable)

  2. critical section

  3. 开中断(enable)

缺点

  • 将禁止中断的权力交给用户进程是有隐患的

  • 限制了处理机交叉执行程序的能力

  • 对多处理机无效

硬件指令test & set

测试和设置指令是一类由处理器硬件支持的机器指令,可以原子性地读取一个变量的值,然后再设置新的值。

test&set(&address)
{
	result = M[address];
	M[address] = 1;
	return result;
}

使用指令进行互斥时,将该函数放入循环中,如:

while(test&set(&address));

互斥锁

为临界资源设置锁位变量w。初始化及退出临界区时,w置为0;进入临界区时w置为1.

  • w=0,资源空闲可用

  • w=1,资源已被占用

int w=0;
void P(int i)
{
    while(true)
    {
        TestSet(w);//加锁
        {critical section}
        w=0;       //开锁
        {remainder section}
    }
}
int main()
{
    w=0;
    Parbegin
        P(1);
    	P(2);
    	P(3);
    Parend
}

自旋锁

利用CAS实现。

void lock_init(int *lock)
{
    //初始化自旋锁
    *lock=0;
}
void lock(int *lock)
{
    while(atomic_CAS(lock,0,1) != 0);
    //循环忙等
}
void unlock(int *lock)
{
    *lock=0;
}

优点:没有上下文切换。

在现代多核计算系统上,自旋锁被广泛应用。

Peterson算法

两个进程共享两个数据项:

  • int turn: 表示哪个进程可以进入临界区

  • boolean flag[2]: 表示哪个进程准备进入临界区

适用于两个进程交替执行临界区与剩余区。

//进程Pi
void Pi()
{
    while(true)
    {
        flag[i]=true;
        turn=j;
        while(flag[j]&&(turn==j));
        {critical section}
        flag[i]=false;
        {reminder section}
    }
}
//进程Pj
void Pj()
{
    while(true)
    {
        flag[j]=true;
        turn=i;
        while(flag[i]&&(turn==i));
        {critical section}
        flag[j]=false;
        {reminder section}
    }
}

2.4.2 信号量和P/V操作

信号量

物理含义:系统共享资源的物理实体

使用结构体描述:

typedef struct{
	int value;             //表示该类资源的可用数量
	struct process *list;  //等待使用该类资源的进程牌堆的队列头指针
}semaphore;

P相当于申请资源,也用wait()或down()表示:

P(S)
{
    s.vaule--;
    if(s.value < 0)
    {
        add this process to s.list;
        block();
    }
}

V相当于释放资源,也用signal()或up()表示:

V(S)
{
    s.value++;
    if(s.value <= 0)
    {
        remove a process from s.list;
        wakeup();
    }
}

vaule > 0时,value的值表示的是可用资源的数量;value < 0时,value的绝对值表示正在等待资源被释放的处于阻塞态的进程的数量

通过信号量实现进程互斥

互斥信号量mutex,初值为1。

do{
    P(mutex);
    {critical section}
    V(mutex);
    {reminder secion}
}while(1);

通过信号量实现进程同步

例如:计算进程Pc和打印进程Pp之间的同步。假设Pc和Pp共同使用一个单缓冲。多个Pc之间互斥。

使用信号量:

  • empty,计算进程使用,表示缓冲区是否为空,初值为1

  • full,打印进程使用,表示缓冲区是否不为空,初值为0

int empty = 1, full = 0;
parbegin
    
//compute process
    begin
    	compute next number;
		P(empty); //申请一个空缓冲
		add the number to buf;
		V(full); //释放一个满缓冲
		...
    end
            
//print process
    begin
        P(full);
		print next number;
		V(empty);
		add the empty to buf;
        ...    
    end        
parend

有多个缓冲区时,empty > 1。

经典进程同步问题:

  • 生产者-消费者问题

  • 读者-写者问题

  • 哲学家就餐问题

2.4.3 Linux内核同步

互斥访问内核共享数据结构。

内核使用的同步技术:每CPU变量。

  • 把内核变量声明为每CPU变量,一个CPU不应该访问与其他CPU对应的变量

  • 为来自不同CPU的并发访问提供保护

  • 问题:

    • 异步函数

    • 内核抢占

2.4.4 进程高级通信

高级通信是指进程采用系统提供的多种通信方式,如消息缓冲、信箱、管道和共享主存区等,实现的通信。

通信进程通过发送消息和接收消息的办法,把通信内容直接或间接地传给对方,一次通信过程可交换若干个信息。

  • 同步通信:阻塞发送,阻塞接收。使用socket

  • 异步通信:非阻塞发送,阻塞接收

消息缓冲通信

有两种实现方法:

  • 消息缓冲池:每个缓冲区可以存放一个消息,进程想要发送消息时,向系统申请一个缓冲区,将消息存入其中,然后把该缓冲区连接到接收进程的消息队列上。消息队列通常放在接收进程的进程控制块中。

  • 信箱:每个信箱可容纳多封信件。

消息缓冲区描述为:

type message buffer = record
	sender: 消息发送者的名字
	receiver: 消息接收者的名字
	size: 消息长度
	text: 消息正文
	next: 指向下一个消息缓冲区的指针
end

操作系统提供了发送原语send()接收原语receive(),通信的双方通过调用这两个原语进行通信。

为使用发送原语和接收原语,修改进程控制块,增加以下字段:

mq: 消息队列头指针
mutex: 互斥使用消息队列的信号量
sm: 消息队列中的消息个数的信号量

发送原语:

send(receiver, a)                 //参数为接收者的名字和发送区的首地址
{
	getbuf(a.size, i);            //按消息大小申请一个缓冲区i
    i.sender = a.sender;          //将消息从发送区移入消息缓冲区
    i.size = a.size;
    i.text = a.text;
    i.next = 0;
    getid(PCB set, receiver, j);  //由PCB集合中得到接收者PCB的标识j
    P(j.mutex);                   //申请进入消息队列
    Insert(j.mq, i);              //将消息插入消息队列
    V(j.mutex);                   //释放消息队列
    V(j.sm);                      //消息个数+1
}

接收原语:

receiver(b)                         //参数为接收区的首地址
{
    j = get caller's internal name; //获得自己的内部标识
    P(j.sm);                        //检查消息队列中是否有消息
    P(j.mutex);                     //若有,申请进入消息队列获取消息
    Remove(j.mq, i);                //从消息队列中取走一个消息送i
    V(j.mutex);                     //释放消息队列
    b.sender = i.sender;            //将消息复制到b区
    b.size = i.size;
    b.text = i.text;
}

2.5 死锁

死锁:某一进程请求已被其他进程占用的资源而进入阻塞状态,导致系统其他进程也因请求资源而处于阻塞状态,这种阻塞等待可能永无止境。

2.5.1 产生原因和条件

产生原因

  • 竞争有限的不可抢占资源

  • 进程推进顺序非法(进程调度顺序不合理)

必要条件

  • 互斥:每个资源是不可共享的

  • 保持和等待:进程因请求资源而被阻塞等待时,对已经分配给它的资源保持不放

  • 不剥夺:进程所获得的资源在未使用完之前,不能被其他进程强行剥夺,只能由获得资源的进程自己释放

  • 循环等待:存在一个进程循环链,链中有多个进程,每个进程都在等待链中的下一个成员保持的资源

2.5.2 解决方法

鸵鸟算法

忽略死锁。严重时,可重启机器或简单地删除一些进程。Unix、Linux和Windows都采用这样的策略。

死锁预防

破坏死锁产生的条件,确保死锁永不产生。

  1. 破坏互斥条件:采用spooling技术,将一台独享设备改造成多台设备以供进程共享使用。不是所有设备都能采用spooling技术。

  2. 破坏保持和等待条件:静态分配资源。

    缺点:

    • 资源利用率低

    • 许多进程在开始之前不能确定所用资源数量

  3. 破坏非剥夺条件:在进程进入阻塞状态前强行释放其占据的不可抢占资源。

    缺点:系统在保护、恢复进程的现场时开销较大

  4. 破坏循环等待条件:有序分配资源。

死锁避免

动态分配资源前进行检测,只有能确定系统在分配资源后是安全的,才分配资源。

银行家算法

  • 当一个进程提出一个资源请求时,假定分配给它,并调用检查系统状态安全性的算法。如果系统是安全的,则把假定分配变为实际的分配。否则,阻塞进程。

  • 检查系统状态安全性的算法。根据系统剩余的资源情况,银行家进行检查,看分配资源后能否让系统中的所有进程都正常完成,即,找到一个进程完成序列。

对于系统中有n个并发进程共享使用m个同类资源时,若每个进程需要的最大资源数量为x,仅当m、n、x满足如下的不等式时,才能保证系统处于安全状态:

已知m和n时,得到x的解:

死锁检测

化简资源分配图。系统在动态分配资源后进行检测。

死锁恢复

检测到死锁存在,如果发生死锁则采取措施恢复。

2.6 管程

提供了与信号量同样的功能,但使用方便,容易控制。

基本思想:将共享变量以及对共享变量进行的所有操作过程集中在一个模块中。

2.7 题目

当前进程的时间片用完后,该进程状态由执行态变为就绪态

用户级线程执行时,同一进程不同线程的切换不需要内核支持。

× 在支持线程的操作系统中,同一个进程中的各个线程共享该进程的用户栈。

一个进程中的所有线程共享进程的地址空间、堆,有各自独立的

当某进程在进程输入输出时,进程的状态处于阻塞或等待状态。当输入输出完成后,该进程被唤醒,其状态将从阻塞变为就绪

进程是程序的执行过程,各进程向前推进的速度是不可预知的,这种性质称作进程的异步性

一定产生进程状态改变的事件是:运行的进程正常退出,运行的进程因种种原因而阻塞,阻塞的进程被唤醒,运行的进程时间片用完

FCFS开销较小

多级反馈队列、SJF、静态优先度调度会产生饥饿现象

降低进程优先级的合理时机是进程的时间片用完

会引起进程创建的是:用户登录、应用请求

PCB通常保存在RAM中。

进程所请求的一次打印输出结束后,将使进程状态从阻塞→就绪

进程与线程的关系:线程不能独立于进程而存在;进程是资源分配的基本单位;线程是处理器调度的基本单位

阻塞原语使一个进程变为阻塞等待状态

一个进程可以使用创建原语建立一个新的进程。

唤醒原语从等待队列中撤出进程。

在操作系统中引入进程概念的主要目的是:描述程序动态执行过程的性质

为了照顾紧迫型作业,应采用优先级调度算法;照顾短作业,采用短作业优先算法;为了能实现人机交互,应采用时间片轮转算法;既能使短作业用户满意又能使长作业用户满意,应采用高响应比优先算法。先来先服务对短进程不利。

创建进程时所做的工作:初始化新进程的进程控制块;给新进程分配一个唯一标识;给新进程分配虚拟地址空间

在支持多线程的系统中,进程P创建的若干个线程不能共享的是进程P中某线程的栈指针

一定会导致进程切换的是:进程执行时产生终止(abort)异常;进程执行过程中时间片到时

截止时间的保证是选择实时调度算法的重要准则

响应时间快是选择分时系统中进程调度算法的重要准则,平均周转时间短是批处理系统中选择作业调度算法的重要准则,优先权高的作业能获得优先服务是为了照顾紧急作业用户的要求而设置的。

√ 执行原语时不会响应任何中断。

并发进程失去封闭性,是指并发进程共享变量,其执行结果与速度有关

关于进程优先级和优先数的叙述中,正确的是:优先数是一个数值;进程优先数决定了进程的优先级;通常情况下系统进程的优先级比用户进程的优先级高

原语有:进程创建原语、进程撤销原语、阻塞原语、唤醒原语、挂起原语、激活原语、改变进程优先级

进程控制原语包括:进程的建立、进程的撤销、进程的等待和进程的唤醒

进程映像=程序代码+用户栈+PCB

√ 执行原语时不会相应任何中断。原语是不可分割的操作。

死锁解除方法:1. 资源剥夺法。挂起某些死锁进程,并抢占它们的资源,将这些资源分配给其他的死锁进程。2. 撤销进程法,强制撤销部分、甚至全部死锁进程并剥夺这些进程的资源。3. 进程回退法。让一个或者多个进程回退到足够避免死锁的地步,回退时自愿释放资源而不是被剥夺。这要求系统保证进程的历史信息,设置还原点。

在使用信号量及P、V操作机制解决问题时,一个进程执行V操作意味着可能有另一个进程从等待队列进入就绪队列

为避免产生死锁,银行家算法破坏了循环等待条件

多个进程并发执行时,各个进程应互斥进入其临界区,其中的临界区是指访问临界资源的一段代码

× 若系统中存在一个循环等待的进程集合,则必定会死锁。

在消息缓冲通信机制中,使用的临界资源是整个消息队列

在使用信号量及P、V操作机制解决问题时,一个进程执行V操作意味着可能有另一个进程从等待队列进入就绪队列

3 内存管理

存储器管理主要涉及的功能

  1. 存储器分配

  2. 地址转换或重定位

  3. 存储器保护

    • 防止地址越界

      • 上下限寄存器

      • 基址+限长寄存器

    • 存取方式检查

  4. 存储器扩充

  5. 存储器共享:页面共享,写时复制

3.1 概述

  • 地址空间(Address Space):程序中的各种符号名的集合所限定的空间,也叫符号名字空间。其中的地址称为相对地址逻辑地址

  • 存储空间(Memory Space):物理存储器中的全部物理单元的集合所限定的空间。其中的地址称为物理地址绝对地址,也叫实地址。

3.2 程序链接与重定位

链接

形成程序的逻辑地址。

将汇编/编译产生的目标代码与所需要的库函数装配成一个可执行映像,即程序。

  • 静态链接:在程序装入内存运行前,就将代码和库函数链接成可执行程序。

  • 动态链接

    • 装入时:一边将目标程序模块装入内存,一边链接。

    • 运行时:程序运行时才进行链接。相比于装入时链接的优点:

      • 便于模块共享

      • 使系统空间和时间的开销最小

      • 系统效率更高

  • 结果:形成程序的地址空间,即一个一维的地址域,其中的各个地址叫做该程序的线性地址或虚地址(相对地址)。通常CPU产生的地址是线性地址。

装入

把用户程序由地址空间装入到存储空间。

  • 绝对装入

  • 可重定位装入:静态重定位,连续存储区

  • 动态运行时装入:动态重定位

重定位

Address Relocatioin

也称装载。把程序的地址空间的逻辑地址转换为存储空间的物理地址。又叫地址映射或地址变换(Address Mapping)。通过存储器管理单元(MMU)实现。

  • 静态重定位(Static Relocation):装入进程时,由装入程序把用户程序中的指令和数据地址全部转换成存储空间的绝对地址。只用于早期的单道批处理和单任务系统中。

    • 发生时间:在程序执行前一次完成

    • 优点:不需要硬件支持,容易实现

    • 缺点:

      • 要求程序占有连续的存储空间。不能共享存储器中的程序

      • 程序在执行时,不允许在主存移动

  • 动态重定位(Dynamic Relocation):靠硬件的地址转换机构实现。在程序执行时,对每一个存储器的访问,都要将相对地址转换成主存的绝对地址。使用重定位寄存器。在存储器管理为程序分配一个主存区域后,装入程序把程序和数据原样装入到分配的存储区中,然后把这个存储区的起始地址送入重定位寄存器中。

    • 发生时间:指令执行过程中进行

    • 允许程序在主存中移动,此时只需要用新地址修改重定位寄存器。

    • 优点:

      • 主存利用充分

      • 允许程序不占有连续的存储空间,可以共享程序

      • 便于多用户共享存储器中的同一程序和数据

3.3 分区管理(连续分配)

把主存划分成若干个连续的区域,每个用户进程占有一个。

固定式可变式
存储分配
  • 大小固定;最小
  • 回收
  • 内部碎片
  • 按需分配 选择合适的算法:首次、最佳、最差
  • 合并空闲区
  • 外部碎片
地址变换静态重定位动态重定位
存储保护上下限寄存器基址+限长寄存器(固定式也可以用)
存储共享××

3.3.1 固定分区

把主存用户区预先划分成几个大小不等的分区,当进程到达时,选择一个适合进程要求的最小空闲分区分给进程;没有空闲分区则等待。

使用静态重定位。

3.3.2 可变式分区

在装入进程时才划分存储空间。当进程申请空间时,系统从空闲的存储空间中划分出大小正好等于进程的一个存储区分配给进程。也叫动态分区(Dynamic Partition)。

使用动态重定位。

分配算法

  • 首次适应(first fit)法:按照地址从小到大的顺序检索空闲区,当出现空闲区满足进程要求时进行分配

    • 优点:优先利用低地址

    • 缺点:遍历列表,效率低

    • 循环首次适应:每次从上次分配的地址开始查找

  • 最佳适应(best fit)法:找到满足进程且最小的空闲区进行分配

    • 缺点:需要查找所有分区,效率低

  • 最坏适应(worst fit)法:找到满足进程且最大的空闲区进行分配

    • 缺点

      • 需要查找所有分区,效率低

      • 可能导致大进程没有空闲区可用

空闲区管理

  • 分区说明表

    • 由两张表格组成:已分配区表和未分配区表,分别记录已分配的分区和空闲区

    • 优点:直观、简单

    • 缺点:表格长度不合理会造成浪费或表格溢出

  • 空闲区链表

    • 将表格信息附加在每个已分配区和未分配区中。

优缺点

  • 优点:

    • 实现了多道程序共享主存

    • 系统设计相对简单

    • 实现存储器保护的手段也比较简单

  • 缺点:

    • 主存利用不够充分

      • 碎片:系统内部一些得不到利用的存储空间

        • 内部碎片:通常出现在固定分区中;存在于进程存储空间内部

        • 外部碎片:可变式分区里;存在于整个内存中

      • 解决办法:

        • 拼接:合并空闲区

        • 进程占据不连续的空间

          • 等大空间:页式管理

          • 不等大:段式管理

    • 没有实现主存的扩充问题

      • 解决办法:

        • 覆盖与交换

        • 虚拟存储器

3.4 覆盖与交换

引入:解决大作业小主存问题。一定程度上对主存进行了逻辑扩充

  • 覆盖:由用户实现,同一主存区可以被一个或多个作业(或进程)的不同程序段重复使用

  • 交换系统根据需要把主存中某个(或某些)暂时不运行的进程的部分或全部信息移到外存,而把外存中的某个(或某些)进程移到相应的主存区投入运行

    • 将交换技术与多道程序技术结合起来,使主存同时保留多个进程,每个进程占用一个分区,这样既减少了交换次数,也降低了各进程的响应时间

3.5 不连续分配

3.5.1 页式管理

允许一个进程占用不连续的存储区域,以克服碎片。会产生内部碎片,在最后一页对应的物理块中。

把主存分成大小相等的块(block),也叫页框(Page Frame);页框数量 = 物理空间大小 / 页框大小。

进程的地址空间也分成同样大小页面(Page),页面数量 = m/I,向上取整。m是程序的大小,I是主存块的大小。分配存储时,以块为单位,将进程的若干页装入可以不相邻接的物理块中。

页表

在分配存储空间时为进程生成一个页表,记录该进程的逻辑页与内存块的映射关系。每个页都有一个表目,记录该逻辑页分配的主存块号。

页表放在主存,且页表在主存的起始地址和页表长度都记录在进程控制块中。

假设物理空间的大小为2^k,逻辑空间的大小为2^m,页的大小是2^n,则:

  • 页表项的个数 = 2^(m-n),即为进程分配了多少页

  • 页表项的大小 = 2^(k-n)位,即物理块的长度为k - n;占据 [ (k-n) / 8] 个字节(B)。

执行一次访内操作至少要访问主存两次:一次是访页表,一次是实现指定操作。

两种计算页号和页内地址的方法:

  • 设进程在逻辑地址空间中的地址为A,一个逻辑地址分解的页号 p = A div 页的大小,页内地址 w = A mod 页的大小。

  • 把A写成m位的二进制数(位数不足的在前面补0),前m-n位表示页号,后n位表示页内地址。

地址分离工作由硬件(MMU)实现

  • 页表基址寄存器(PLBR):指向页表

  • 页表长度寄存器(PLTR):页表长度

快表和联想存储器

为了提高页式地址变换的效率,设置一个专用的具有并行查找能力的硬件高速缓冲寄存器组,叫做联想存储器(TLB),存储最近用过的大多数的页表项。存储在TLB中的页表项叫做快表,它和存储单元能被同时读取,并与虚页值同时比较。

页表连续存储。

TLB存储的是最近被访问的逻辑页及其对应的物理块。

  • 结构:

    • 页号

    • 块号:页号对应的物理块

    • 访问位:指示快表项最近有没有被访问过。当所有的快表项都被占用,新来的快表项要选择一个代价最小的(最近没有被访问过),将其替换掉

    • 状态位:0表示空闲,1表示被占用

  • 进行地址变换时,有两个变换过程:

    • 利用快表进行的快速变换过程

    • 利用主存页表进行的正常变换过程

    一旦快表找到结果,则得出访问主存的绝对地址,只需要访问一次主存;称作快表命中

    否则进行正常的变换过程,即快表未命中。并更新快表,将进程写入快表中访问位为0的一项

主存分配与保护

  • 页表:每个进程一个,放在主存的专门区域

  • 进程控制块:存放该进程的页表在主存的始址和页表长度(即进程地址空间的大小)

  • 存储空间管理

    • 存储分块表:表的第一项指出当前主存空闲块综述,第二项为指向第一个空闲块的指针,各空闲块通过单向链链接在一起

    • 位示图:每一个存储块对应位示图中的一位,0表示空闲,1表示占用

  • 存储器共享与保护

多级页表

为了让页表不连续存放,提出多级页表。把页表再分页:

假设系统为m位(存储空间为2^m),物理块大小为2^n,则每页可以包含2^(m-n)个表项。若表项的大小为2^k,

  • 外层

    • √ 外层页号,长度为m-n-(n-k)=m-2n+k

    • √ 外层页内地址,长度为n-k,即放了多少个表项

  • √ 页内地址,长度为n,即一个物理块内能存放的页表项个数

对内存的访问次数比快表多。

地址空间超过32位:使用哈希页表。以逻辑页号作为哈希值

3.5.2 段式管理

基本思想

  • 程序按内容或过程(函数)关系分成段,每段有自己的名字。一个用户作业或进程所包含的段对应于一个二维线性虚拟空间,也就是一个二维虚拟存储器

  • 段式管理以段为单位分配内存,然后通过地址映射机构把段式虚拟地址转换成实际的内存物理地址。

  • 和页式管理一样,段式管理只允许经常访问的段驻留内存,将来一段时间内不被访问的段放入外存,待需要时自动调入。

  • 内存分配与释放在作业或进程的执行过程中动态进行。

地址结构

<段号S,段内地址W>

段表

在进行初始内存分配之前,首先根据用户要求的内存大小为作业或进程建立一个段表,一般在内存中给出一块固定的区域放置段表。包含:

  • 段号:与用户指定的段名一一对应。

  • 始址:该段在内存或外存的物理地址

  • 长度:段的长度

  • 存取方式:对该段进行保护,只有处理机状态字中的存取控制位与段表中存取方式一致时才能访问该段

  • 内外:表明该段现在存储于外存还是内存中。如果在外存,则发生中断。

  • 访问位:根据淘汰算法的需要设置。

地址访问

  1. 进程开始执行时,管理程序通过访问段表寄存器得到该进程的段表始址,把段表放入段表地址寄存器。

  2. 依据虚地址中的段号s为索引查段表。如果该段在内存,则判断其存取控制方式是否有错。

  3. 存储控制方式正确,则从段表相应表目中查出该段在内存的起始地址,并将其和段内相对地址w相加,得到实际内存地址。

  4. 如果该段不在内存,则产生缺段中断将CPU控制权交给内存分配程序。

  5. 内存分配程序首先检查空闲区链,查找是否有足够长度的空闲区装入需要的段。

  6. 如果内存中的可用空闲区总数小于要求的段的长度,则检查段表中访问位,淘汰那些访问概率低的段并将需要段调入。

3.5.3 段页式管理

3.6 虚拟存储

页面失效:该页未装入主存,需要从辅存中调页。

页面争用(冲突):两个以上的虚页想要进入主存中同一页面位置。

页面失效不一定发生页面冲突,页面争用一定由页面失效引起。

3.6.1 基本概念

虚拟存储的提出是为了解决一个问题:内存容量不足以容纳大进程时,进程无法执行。

虚拟存储器:具有请求调入功能和置换功能,能从逻辑上对内存容量加以扩充的一种存储器系统。

特征

  • 多次性

  • 对换性

  • 虚拟性

实现原理

页式管理+交换技术

将进程信息的副本存放在外存中,并在页表中指出各页对应的外存地址。当进程被调度运行时,先将进程中的较少页装入主存,在执行过程中,访问不在主存的页时,再将其调入。

程序运行前不必全部装入内存,在运行过程中也不必一直驻留在内存。

页表结构

包含以下信息:

  • 页号

  • 物理块号

  • 状态位

    • 指示该页是否在主存

    • 0:不在主存,产生缺页中断

    • 1:在主存

  • 外存地址

  • 访问位

    • 指示该页最近是否被访问过

    • 0:未访问过

    • 1:访问过

  • 修改位

    • 指示该页调入主存后是否修改过

    • 0:未修改过

    • 1:修改过

3.6.2 缺页中断处理

操作系统接到中断信号后,调出缺页中断处理程序。如果内存中有空闲块,则分配一页,根据页表中给出的外存地址,将新调入页装入内存,并修改页表中相应页表项的状态位及对应的内存块号。

如果没有空闲块,则需要淘汰某页。如果该页被修改过,则需要将其写回外存。

在调页期间,请求调页的进程置为阻塞态;在缺页中断时,一条指令没有执行完,在中断处理后应该重新执行被中断的指令。

3.6.3 页面置换算法

抖动(Thrashing):刚淘汰的页面马上又要调用,因此再次装入;调入不久再被淘汰,淘汰不久再次装入。这样的过程反复出现,使整个系统处于频繁的调入调出状态,大大降低了系统的处理效率。

解决抖动:撤销部分进程;优化页面置换算法

置换策略

  • 局部置换

    • 固定分配

    • 只置换当前进程占用的物理页面

    • OPT/FIFO/LRU/时钟算法

  • 全局置换

    • 为进程分配可变数目的物理页面

    • 工作集算法、缺页率算法

算法

  • FIFO:先进先出

    • 会出现Belady异常:分配给进程的物理块增加时,缺页次数反而也增加

  • LRU:淘汰最近最久没有使用的页面。

    • 硬件实现:使用一个计数器,每次调用进程时对应计数+1,淘汰页面时选择计数最小的页面

    • 软件实现:把最近访问的调到队尾,从队首开始淘汰

  • LFU:淘汰最近最少使用的页面。

  • OPT:选择今后不再访问或在最长一段时间之后才需要访问的页面进行淘汰。理论上最优的页面淘汰算法,实际无法实现

  • 时钟页面置换算法

    • 将进程所访问的页像时钟一样存放在一个循环链中

    • 设置一个指针指向最早进入主存的页

    • 产生缺页中断时,按照下列原则选择某一页面进行淘汰:

      1. 检查指针指向的进程的访问位,如果为0,淘汰该页并把新装入的页插入到该位置,指针向前移动一个位置

      2. 如果为1,将访问位置0,并将指针前移一位,直到找到访问位为0的一页,将其淘汰

确定页面大小

页面越大,无用程序装入主存就越多,从而使主存浪费严重;页面越小,程序需要的页越多,页表越大。

最佳页尺寸:设进程平均大小为s字节,页的大小为p字节,页表项占e字节,则:

  • 进程所需页数近似为s/p页

  • 页表占用空间为s*e/p字节

  • 进程内部碎片浪费空间平均为p/2

  • 页表和内部碎片引起的系统总开销为se/p+p/2

  • 最佳页面大小为:

工作集

概念:在某段时间间隔里,进程实际所要访问页面的集合。

3.7 题目

在虚存管理中,地址变换机构将逻辑地址变换为物理地址,形成该逻辑地址的阶段是链接

负责虚拟地址到物理地址的映射的是MMU

把作业地址空间使用的逻辑地址变成内存物理地址的是重定位

动态分区分配算法中,容易产生很多小碎片的是最佳适应

在可变分区管理方式下,在回收内存时,若已判断出“空闲区表中某一表项的起始地址恰好等于被回收分区的起始地址与长度之和”,则表示被回收分区有上邻空闲区上邻是指地址更大的区域

分区存储管理系统中,硬件只要提供一个基址寄存器和一个限长寄存器,就可以为多个进程的并发执行提供存储保护并完成地址变换。

存储管理中采用覆盖的目的是:节省主存空间

√ 操作系统实现进程切换时会刷新TLB

位示图法可用于:页式存储管理中空闲区的分配和回收

系统发生抖动时,可以采取的有效措施是撤销部分进程

页面分配策略与页面置换策略不能组合使用的是固定分配,全局置换

页式管理和段式管理都采用动态重定位

4 文件系统

参考:

【操作系统】文件管理(六) - leesf - 博客园

文件系统管理的对象有:

  • 文件:文件管理的直接对象

  • 目录

  • 磁盘存储空间

4.1 用户角度

4.1.1 文件目录结构

文件目录:记录文件的名字及其存放物理地址的一张映射表,表中包括了许多文件控制块。与文件一样,存放在文件存储器中。通常采用多级目录结构。

  • 实现用户按文件名存取文件存储器上的信息

  • 使用方便灵活,安全可靠

  • 便于文件的共享和保密

4.1.2 文件操作命令

  • create

    • 在指定设备上位指定路径名的文件产生一个目录项(不一定是空的),并设置文件的有关属性,如文件名、文件存取方式,并将文件大小置为0。返回文件描述符

  • delete

    • 根据文件的路径名找到指定的目录项,根据目录项信息回收文件占用的各个物理块,再将文件的目录项置为空(可用)

  • open

    • 按照文件路径名找到文件目录项,进而找到FCB信息,之后把FCB复制到内存,并记录到系统打开文件表

    • 系统打开文件表由系统中的文件对象组成的链表,文件对象记录了该文件的读写位置指针、文件打开方法和共享该文件对象的进程数等信息

      • Linux系统中,文件对象的地址记录在进程打开文件表里,返回给进程的是进程打开文件表的索引

      • Windows系统中,文件对象的地址记录在进程句柄表里,返回给进程的是句柄表的索引

    • 进程打开文件表

  • close

    • 释放文件使用时的所有主存资源

4.1.3 文件逻辑结构

用户可以决定文件逻辑结构。

  • 无结构的字符流:由先后到达的字节流组成,其长度就是它所包含的字节个数。

    • 对于源程序、可执行文件、库函数等通常采用的是无结构文件形式,即流式文件,其长度以字节为单位。

  • 有结构的记录文件:由若干字段组成的一些相关联的信息项。每个记录都用于描述实体集中的一个实体,各记录有着相同或不同数目的数据项

    • 定长记录:文件中所有记录的长度都是相同的,所有记录中的各数据项都处在记录中相同的位置,具有相同的顺序和长度。记录长度=记录个数×记录长度

    • 变长记录:文件中个记录的长度不相同,可能由于一个记录中所包含的数据项目并不相同。记录长度=各记录长度之和

    • 记录组块与分解

      • 组块:把多个逻辑记录存放在一个物理块中

      • 分解:从一个物理块中将一个逻辑记录分离出来

    • 可采用多种方式来组织这些记录:

      • 顺序文件:记录按照某种顺序排列所形成的文件,记录通常是定长的,能较快查找到文件中的记录

      • 索引文件:记录为可变长度时,通常建立一张索引表,并为每个记录设置一个表项,加快对记录检索的速度。索引表本身是一个定长记录的顺序文件

      • 索引顺序文件:将顺序文件中的所有记录分为若干个组,为顺序文件建立一张索引表,在索引表中为每组中的第一个记录建立一个索引项,其中含有该记录的键值和指向记录的指针。

4.1.4 文件访问方式

  • 顺序访问

  • 直接访问

4.2 文件系统

文件系统是操作系统中管理文件的软件结构,是用户和外存设备之间的接口。

主要目的是实现对文件的按名存取;重要作用之一是在用户逻辑文件和物理文件之间建立映射。

文件

  • 文件:一组带标识的、在逻辑上有完整意义的信息项的序列

  • 一个文件由两部分组成:文件控制块——元数据,文件体——数据。

  • 从用户角度看,文件是存储在外部存储器的具有符号名的相关信息的集合。

  • 从操作系统角度看,文件具有一些属性,包含在文件控制块FCB中:

    • 文件名

    • 文件标识:操作系统管理文件的唯一标识

    • 文件类型:扩展名

    • 文件位置:文件在磁盘上的地址

    • 文件大小:以字节或块为单位

    • 文件保护方式:读、写、执行等

    • 文件的创建或修改日期

    • 存取控制信息

    • 文件物理结构

  • FCB保存在文件目录中,每个文件在其中占有一项;目录以文件形式存储在外存

文件分类

  • 按用途分:系统文件、库文件、应用程序文件和用户文件

  • 按保护方式分:只读文件、读写文件、无保护的文件

  • 按信息流向分:输入文件、输出文件、入/出型文件

  • 按设备分:硬盘文件、软盘文件、磁带文件

  • Unix系统中,为方便用户操作文件,按文件的组织和处理方式分成如下三类:

    • 普通文件:包括系统文件、库文件、应用程序文件和用户文件

    • 目录文件:由文件目录构成的文件

    • 特别文件:系统中所有的输入、输出和输入/输出型设备,以及其他一些特殊文件

提供功能:

  • 管理磁盘、磁带等组成的文件存储器

  • 实现用户的按名存取

  • 提供灵活多样的文件结构和存取方法

  • 提供一套方便、简单的文件操作命令

  • 保证文件信息的安全性

  • 便于文件共享

文件共享

共享:允许多个用户共同使用同一个文件

  • 链接计数(索引结点),硬链接

    • 查找方式:硬链接→索引结点→文件内容

    • 文件目录中只设置文件名及指向相应索引结点的指针

    • 索引结点中存放文件的物理地址及其他的文件属性等信息

    • 删除时,链接计数-1,并删除自己目录中相应的目录项(硬链接),而不是直接删除文件内容。链接计数=0,表示没有用户使用该文件,系统负责删除该文件

    • 不可以对目录建立硬链接

  • 符号链软链接

    • 查找方式:软链接→被链接文件→索引结点

    • 删除一个软链接,不影响被链接的文件;删除被链接的文件,则软链接无法找到原文件,变成悬挂的软链接;但原文件被重新创建(按原路径)时,软链接又重新发挥作用

    • 需要根据文件路径名逐个查找文件,直到找到该文件的索引结点,访问开销大,磁盘启动频率高

    • 符号链的索引结点也需要耗费磁盘空间

    • 新建和删除软链接不会改变链接计数值

    • 可以对目录建立软链接

当新文件建立时,一般默认引用计数值为1。

硬链接可以看作是已存在文件的另一个名字,新文件和被链接文件指向同一个节点,引用计数值加1。当删除被链接文件时,只是把引用计数值减1,直到引用计数值为0时,才能真正删除文件。

软链接又叫符号链接,在新文件中只包含了被链接文件的路径名,新文件和被链接文件指向不同的节点。建立软链接文件时,文件的引用计数值不会增加。在这种方式下,当被链接文件删除时,新文件仍然是存在的,只不过是不能通过新文件访问被链接文件而己。

文件保护

  • 文件复制:对系统保存的所有文件进行双份或多份复制,防止自然灾害和硬件、软件错误造成磁带、磁盘上的数据受到破坏

    • 周期性全量转存(massive dump):按固定时间间隔把文件存储空间中的全部文件转存到某一存储介质

    • 增量转储(incremental dump):每当用户退出系统时,系统将他这次从login登录到logout退出使用过程中,新创建和修改过的文件以及文件的有关控制信息转储到磁盘或磁带上。需要文件在目录下中有修改标记

  • 增设防护设施:防止其他用户对文件的有意破坏或窃取文件

文件存取控制

  • 保护域

  • 存取控制表ACL:按列存储

    • 每个对象有一个有序表,包含了有权存取该对象的所有域,叫做ACL

  • 存取权限表:按行存储

内存映射文件

存储器映射文件允许进程分配虚存的一部分地址空间,然后将磁盘上的一个文件映射到该空间,对文件块的存取是通过访问虚存的一个页来实现的。映射一个文件到虚存是操作系统提供的一个系统调用

4.3 物理存储

文件物理结构

指一个文件在文件存储器上的存储方式及其和文件逻辑结构的关系。

把文件存储器的空间划分为若干个大小相等的物理块,一个物理块可以包括一个扇区或几个连续的扇区。存储在文件存储器上的文件称为物理文件,存放文件记录的物理块叫物理记录。对于记录式文件,文件的逻辑记录不一定正好等于物理块的大小。

分类

  • 连续文件:也叫顺序文件,逻辑上连续的文件信息存储在连续的物理块

    • 优点:实现简单;支持顺序存取和随机存取;存取速度快

    • 缺点:不灵活;容易产生碎片

    • 适合存储操作系统和实用程序一类长度不变的系统文件

  • 链接文件:为了克服采用连续结构产生的碎片问题,逻辑上连续的文件信息分配到不连续的物理块

    • 隐式链接:存放信息的每个物理块中设置一个指针指向下一个物理块,最后一个物理块的指针是0,指示该块是链尾。

      • 优点:允许文件动态增长,使用灵活;不仅允许文件在尾部增长,也允许在两个记录之间插入或删除一个或多个记录

      • 缺点:只能顺序存取,效率低;需要额外空间存储指针

    • 显式链接:把指针字存储在一个专门的索引中,表的长度就是文件存储器能划分的物理块数。该表叫做盘文件映射表或文件分配表FAT,在整个磁盘只设置一张,初始化后放在主存。

      • 优点:提高检索速度,减少访问磁盘的次数

      • 缺点:不支持高效的直接存储;FAT需要占用较大的内存空间;在系统工作期间,整个表必须在主存。

  • 索引文件:为每一个文件建立一个索引表,把分配给该文件的所有盘块号都记录在该索引块中,该表指出文件的逻辑块和物理块的映射关系。

    • 如果文件记录很多,一个索引块放不下,索引表需要占用几个物理块,这时可以将各索引块构成链表,文件目录中指出索引表所在的第一个索引块块号。

    • 当索引表很大时,可以把索引表看成一个文件,并且通过增加一级索引来查找它

    • 优点:支持顺序存取和随机存取;允许文件动态修改;使用灵活;允许用户按照要求直接对文件进行存取;没有外部碎片

    • 缺点:增加存储开销;降低文件存取速度,因为每个文件的存取至少访问外存两次:一次访问索引表,一次访问文件信息

  • 混合索引:多种索引分配方式相结合,如直接地址,一次间接地址,多次间接地址

目录管理

目标:

  • 实现按名存取

  • 提高对目录检索速度

  • 文件共享

  • 允许文件重名

一个文件目录也可以被看成是一个文件,称为目录文件

目录结构:

  • 单级目录结构:整个系统设置一张目录表,每个文件占一个目录项,目录项中含文件名、文件扩展名、文件长度、文件类型、文件物理地址、状态位(表示目录项是否空闲)等

    • 优点:简单,能实现按名存取

    • 缺点:查找速度慢,不允许重名不便于实现共享

  • 两级目录结构:为每个用户建立一个单独的用户文件目录UFD,这些文件目录具有相似的结构,由用户所有文件的文件控制块组成。此外,系统中还有一个主文件目录MFD(Master File Directory),在主文件目录中,每个用户目录文件都占有一个目录项,其目录项包括用户名和指向用户目录文件的指针

    • 优点:提高了检索目录的速度;在不同的用户目录中,可以使用相同的文件名;不同用户还可使用不同的文件名来访问系统中同一个共享文件。

    • 缺点:在多个用户需要合作完成一个大任务时,不便于用户之间共享文件

  • 多级目录结构:也称为树形目录结构,主目录称为根目录数据文件称为树叶其他的目录均作为树的结点

    ​​​​​​​
    • 为了存取灵活,应该允许在一个目录文件中的目录项既可以作为目录文件的FCB,又可以是数据文件的FCB。

    • 系统中的每个文件都有唯一的路径名

 

存储空间管理

  • 空白文件目录(空闲表):空白文件是一个连续未用的空闲盘块区,系统为这些空白文件建立一张表,叫做空白文件目录。

    • 适合文件的静态分配,即连续结构的文件分配

  • 空闲链表

    • 空闲盘块链:把所有空闲盘块连接成一个链。主存保留一个链头指针,但效率比较低。

    • 空闲盘区链:一个盘区包括一个或多个盘块,把所有空闲盘区连接成一个链,在每个盘区上含有指示下一个空闲盘区的指针,以及能指明本盘区大小(盘块数)的信息

  • 位示图:使用一个位向量,每个块占用其中的一位。

    • 优点:容易找到一个或几个连续的空闲块;尺寸固定,通常也比较小,适合存在主存,从而高速地实现文件的分配和回收工作

    • 缺点:磁盘空间大时不适用

  • 空白块成组链表:空闲块自己管理空闲块,每个磁盘块记录尽可能多的空闲块而组成一组,各组之间也用链指针链在一起。

    Linux实例

DOS文件卷结构

文件物理结构是链接文件

文件卷是指可独立拆卸的文件系统。

  • 盘片,磁道,扇区,柱面,磁头

    • 盘片:硬盘有多个盘片

    • 磁头:每个磁盘有两个面,每个面有一个磁头

    • 磁道:以盘片中心为圆心,不同半径的同心圆

    • 扇区:盘片被分成扇形的区域

    • 柱面:不同盘片相同半径的磁道组成的圆柱。为了减少移动臂花费的时间,每个文件信息是按柱面顺序存放的

    • 存储容量=磁头数×磁道(柱面)数×每道扇区数×每扇区字节数

    • 信息记录可以表示为:驱动器号,磁道(柱面)号,磁头号,扇区号

  • :DOS进行分配的最小单位。不同的存储介质有不同大小的簇。簇 的大小可在磁盘参数块BPB中获取。簇的概念仅适用于数据区

  • DOS操作系统支持的文件系统由四部分组成:

    • 引导或保留扇区:占用分区的第一个扇区,即硬盘物理地址0面0道1扇区。属于整个硬盘。用作数据盘时保留不用,用作系统盘时用于读入并引导操作系统。包括三部分:

      • 硬盘主引导程序

      • 描述各个分区划分情况的信息表

      • 分区扇区的结束标识AA55h

    • 文件分配表:由若干扇区组成,用来指出整个文件存储空间的使用情况,哪些扇区被使用,哪些空闲。FAT2是FAT区的备份。

    • 根目录区:由若干扇区组成,记录根目录中保存的文件和子目录情况

    • 文件数据区:存放系统文件、子目录文件和各种各样的应用程序和用户文件

  • 读取

    • 寻道时间:磁头做径向移动,到相应的磁道(柱面)上

    • 旋转延迟时间:磁盘做圆周运动,磁头定位到指定扇区

    • 读写传输时间:读写扇区,实现磁盘与主存之间的数据传输

4.4 题目

一个文件系统中,FCB 占64B,一个盘块大小为1KB,采用一级目录,假定文件目录中有3200个目录项,则查找一个文件平均需要__次访问磁盘?

一个文件目录项对应一个文件控制块,我们查找一个文件是不是查找它的目录项即可,顺序查找目录表平均需要查找1600次(n个元素的顺序表平均查找次数为(n+1)/2),一个磁盘块大小为1KB,一个文件控制块大小为64B,一个磁盘块中有1KB/64B=16个文件控制块,相当于查找了1600/16=100个磁盘

用户打开文件表中记录:系统打开文件表入口指针、读写指针、文件描述符,不记录共享计数

能决定文件逻辑结构的是用户,物理结构的是操作系统

× 成组链接法是文件系统中可以采用的文件的物理结构。

磁盘空间分配时,采用链接分配方式不会产生外部碎片,但可能产生内部碎片。

5 I/O管理

管理和控制计算机的所有输入/输出设备是操作系统的主要功能之一。

设备管理的目标

1、向用户提供外部设备的方便、统一的接口,按照用户的要求和设备的类型,控制设备工作,完成用户的输入输入请求。

2、充分利用中断技术、通道技术和缓冲技术,提高CPU与设备、设备与设备之间的并行工作能力,以充分利用设备资源,提高外部设备的使用效率。

3、设备管理就是要保证在多道程序环境下,当多个进程竞争使用设备时,按照一定的策略分配和管理设备,以使系统能有条不紊地工作。

设备管理的功能

1、设备分配和回收;

2、管理输入输入缓冲区;

3、设备驱动,实现物理I/O操作;

4、外部设备中断处理;

5、虚拟设备及其实现。

5.1 I/O设备

  • 根据设备传输速率分类:

    • 慢速设备

    • 快速设备

  • 根据设备共享属性分类:

    • 独占设备:慢速,字符

    • 共享设备:快速,块

    • 虚拟设备:spooling技术

  • 根据数据传输单位分类:

    • 字符设备:以字符为单位发送、接收数据

    • 块设备:以为单位发送、接收数据

5.2 I/O控制方式

书上P130

程序查询不需要硬件支持,其他的都需要。

程序查询

polling

数据传输的基本单位是字符(字节)。

CPU一直循环查询设备是否已经完成。

CPU与设备完全串行工作,CPU的利用效率极低。

程序中断

interrupt

数据传输的基本单位是字符(字节)。

一定程度上让CPU可以与设备并行工作。但会让CPU忙于中断处理,几乎不能做其他计算;如果不能及时处理,会导致数据丢失或其他错误。

直接存储器访问

DMA

数据传输的基本单位是数据块。

磁盘设备与存储器之间的数据传送期间不需要CPU介入,处理机仅在数据传输的开始和完成时进行简单的干预处理,减轻CPU负担。

通道

通道的类型:

  • 字节多路通道:以字节为单位传输信息,可以分时地执行多个通道程序。

  • 选择通道:以成组方式工作,每次传送一批数据,速度很高。在一段时间内只能执行一个通道程序,只允许一台设备进行数据传输。

  • 数组多路通道:结合上面两种方式的优点。先为一台设备执行一条通道指令,然后自动转接,为另一台设备执行一条通道指令。

5.3 I/O软件系统

设计目标

  • 设备独立性:应用程序独立于使用的设备,让设备分配灵活

  • 设备统一命名:一个文件或设备的名字不依赖于具体的设备,即设备的逻辑名。所有文件和设备都使用相同的工具——路径名进行检索

  • 出错处理:数据传输中的错误应尽可能地在接近硬件层上进行处理,仅当低层软件无能为力时,才将错误上交高层处理

  • 缓冲技术:设法使数据的到达率与离去率相匹配,以提高系统的吞吐率,减少中断次数

  • 设备分配:独占型设备/可共享型设备

软件层次

  1. 用户空间I/O软件

    • I/O库函数

    • spooling技术:为了满足多进程对独占设备的共享而引入的技术,用于实现虚拟设备,即在一类设备上模拟另一类设备的I/O技术。实际上是一种缓冲技术,也叫缓输出技术以空间换时间

      • 目的:将独占设备改造为共享设备

      • 构成:

        • 输入/输出井

        • 输入/输出缓冲区

        • 输入/输出进程

  2. 独立于设备的软件

    • 功能:

      • 与设备驱动程序的统一接口

      • 设备命名:把设备的符号名映射到正确的设备驱动程序

      • 设备保护

      • 提供与设备无关的块尺寸:向较高层掩盖不同磁盘采取不同的扇区尺寸这一事实,并提供大小统一的块尺寸。较高层的软件使用等长的逻辑块而独立于物理扇区的尺寸

      • 缓冲技术:改善I/O设备和CPU之间速度不匹配的情况,并减少启动设备次数

        • 单缓冲:用户进程处理和设备读写数据串行,系统效率低

        • 双缓冲

        • 多缓冲和缓冲池:多进程共享缓冲池

      • 设备的分配与释放

      • 报告错误信息

  3. 设备驱动程序

    与设备密切相关的代码放在设备驱动程序层。

    设备驱动程序的任务是接收来自与设备无关的上层软件的抽象请求,并执行这个请求。

  4. 中断处理程序

    每个进程启动一个I/O操作后阻塞等待操作完成。当I/O操作完成并产生一个中断时,CPU响应中断,保护完当前程序的运行现场后,转去执行中断处理程序。用户进程不知道中断的产生和处理过程。

再下一层就是I/O硬件

5.4 磁盘管理

磁盘编址、磁盘访问时间:参考dos文件系统

磁盘调度

  • 先来先服务

    完全不考虑队列中的请求情况,使磁头有最大移动距离

  • 最短寻道时间优先 SSTF

    磁头移向下一请求磁道时,总是选择移动距离最小的磁道。比FCFS优越,但仍不是最好。

  • 扫描法 SCAN

    读写头在开始由磁盘一段向另一端移动时,随时处理所到达的任何磁道上的服务请求,直到移到磁盘另一端,然后反转方向,继续处理磁道上的服务请求。

    在使用SCAN之前,不仅要知道磁头移动的最后位置,还要知道磁头的移动方向

    循环扫描 C-SCAN:磁头回程时不处理任何请求,将磁道排列视为一个环,最后一个磁道与第一个磁道紧密相接,以此达到对磁道上请求的均衡服务

  • 查询法 LOOK

    磁头在向任何方向移动时都只移到最远的一个请求磁道上,一旦在前进的方向上没有请求到达,就回程。即在磁头向前移动之前,先查询前方磁道有无请求,若无就反转方向。同理有循环查询 C-LOOK

SCAN和C-SCAN对磁盘负载较重的系统更为合适;磁盘等待队列中的请求数量很少超过一个时,所有算法都等效,采用FCFS。

5.5 题目

关于操作系统的说法正确的是:操作系统应尽量对设备提供各种不同的接口;操作系统对用户屏蔽了实现具体设备I/O操作的细节;SPOOLing技术是一类典型的虚拟设备技术;设备管理利用各种技术提高CPU与设备、设备与设备之间的并行工作能力;设备管理使用户能独立于具体设备的复杂物理特性而方便地使用设备

× 打印机是典型的块设备

I/O控制方式中,不需要硬件支持的是程序查询

DMA方式是在I/O设备和主存之间建立一条直接的通路

计算数据所在磁盘的柱面号、磁头号、扇区号的程序是设备驱动程序

关于spooling技术说法正确的是:SPOOLing技术需要利用磁盘空间作为缓冲;SPOOLing技术解决了独占设备利用率低的问题;SPOOLing技术以空间换取时间;SPOOLing解决了CPU的速度与设备速度的差异性。

6 Linux系统

6.1 进程管理

6.1.1 进程结构

进程控制块用结构 task_struct 表示,包含与进程相关的所有信息。每个进程有唯一的进程标识符pid。每个进程的核心栈和基本信息 thread_info 放在两个连续的页框(8KB)中。

6.1.2 进程状态

分为两类,由 task_struct 中的 state 和 exit_state 分别表示

  • state 表示进程生命期中的状态,包括:

    • 可运行态:正在或准备在CPU上运行的程序

    • 可中断的等待态:进程睡眠等待系统资源可用或收到一个信号后,进程被唤醒

    • 不可中断的等待态:进程睡眠等待,直到一个不能被中断的事件发生

    • 暂停态

    • 跟踪态:进程的执行被debugger程序暂停

  • exit_state 表示进程的退出态,包括:

    • 僵死态:进程已经终止执行,等待父进程做善后处理

    • 死亡态:父进程发布wait()类系统调用之后,系统删除该终止进程。

状态转换:

 

6.1.3 进程组织

  • 传统进程链表

    进程描述符结构中有几个类型为 list_head 的字段,用于建立进程链表。

    • 所有进程链表

    • 可运行进程链表

    • 子进程链表

    • 兄弟进程链表

    • 等待进场链表

    没有为处于暂停、僵尸或死亡状态的进程分组并建立链表

  • 哈希链表

    为了加速对进程的检索,定义了4类哈希表。内核初始化期间为4个哈希表分配存储空间,并把它们的地址存入 pid_hash 数组中。哈希表的长度依赖于可用RAM的容量

6.1.4 进程控制

进程创建

  • clone():创建轻量级进程函数

  • fork():子程序采用写时复制技术共享父进程的资源

  • vfork():创建成功后暂时挂起父进程

  • kernel_thread():创建内核线程的函数

    内核线程:

    • 0号进程:所有进程的祖先进程,又叫idle进程或swapper进程。每个进程都有一个0号进程

    • 1号进程:0号进程创建的内核线程,也叫init进程,被创建后执行init()函数,负责完成内核的初始化工作。与0号进程共享每个进程所有的内核数据结构。在系统关闭前一直存在。

进程撤销

进程终止:

  • exit():只终止某一个线程

  • exit_group():终止整个线程组

6.1.5 进程切换

只发生在内核态。

schedule() 函数实现。分两步:

  1. 切换页目录表以安装一个新的地址空间

  2. 切换核心栈硬件上下文

6.1.6 进程调度

Linux 2.4-

采用基于RR策略的运行队列。

Linux 2.4

采用O(n)调度

  • 选取所有任务中动态优先级最高的任务进行调度

  • 在运行时计算动态优先级,保证实时任务的优先级高于非实时任务

  • 所有任务存储在一个全局运行队列

  • 缺点:开销大,多核扩展性差

Linux 2.6.0

O(1)调度

  • 两级调度;抢占的,基于可变优先级的调度

  • 两个独立的优先级范围:

    • 优先数越小,优先级越高

    • real-time: 0~99,静态优先级

    • nice: 100~139,动态优先级

  • 给优先级高的分配更长的时间片

优先数与时间片

静态优先级:
time slice=\begin{cases} max ((140-realtime)*20,MIN\_TIMESLICE ), realtime<120\\ max( (140-realtime)*5,MIN\_TIMESLICE ), realtime>=120\end{cases}

动态优先级:
nice=max(100,min(realtime-bonus+5),139)

bonus:0~10,bonus < 5 时降低动态优先级,> 5 时提高动态优先级,其值取决于进程过去的行为

  • 根据程序使用CPU的情况动态调整进程的优先级

  • 提高长时间未获得CPU的进程的优先级

  • 降低运行时间较长的进程的优先级

运行队列

每个运行队列包括两个优先级队列:

  1. 活动的:在其时间片中尚有剩余时间的任务

  2. 到期的:一个任务耗尽其时间片后,被认为是到期的

当活动队列为空时,两个优先级队列互相交换

Linux 2.6.23+

采用完全公平调度CFS

思想:为每个任务分配一定比例的CPU处理时间,既保证公平选择进程,又保证高优先级进程获得较多运行时间。

设置一个虚拟时间vruntime,与实际运行时间之间存在一个映射。优先级越高的进程,nice值越低,单位vruntime对应的实际运行时间越长。CPU公平地为每个进程分配同样多的vruntime。


vruntime=实际运行时间*NICE_0_LOAD = 实际运行时间*1024/进程权重

NICE_0_LOAD=1024,表示nice值为0的进程的权重。

所有进程的vruntime值大小相同:
vruntime=调度周期*1024 / 所有进程总权重

 

CFS使用红黑树作为运行队列。

6.2 内存管理

  • 基于虚拟页式存储管理的虚拟存储

  • 二级页表处理逻辑地址到物理地址的转换

  • 分为物理内存管理、内核内存管理、虚拟内存管理、内核虚拟内存管理、用户级内存管理

  • 使用位示图

6.2.1 空间布局

使用虚拟地址空间,地址由低到高分别为:

  1. 只读段:包括代码段、rodata段(C常量字符串和#define定义的常量)

  2. 数据段:全局变量、静态变量

  3. 堆:动态内存,malloc、new分配

  4. 文件映射区域:一般是mmap函数分配的虚拟地址空间

  5. 栈:维护函数调用的上下文空间,一般为8M

  6. 内核虚拟空间:用户代码不可见的内存区域,由内核管理,如页表

32位系统,每个进程的地址空间为4GB;64位,为2^48

4G线性虚拟地址空间:

  • 低3G:进程私有地址空间

  • 高1G:进程共有地址空间(内核空间)

私有地址空间

虚拟内存区域VMA

  • 一个VMA对应一块连续的线性地址空间,大小是页的整数倍

  • 组织:

    • 单链表

    • 红黑树

  • 分配/释放

    • 分配:do_mmap()

    • 释放:do_munmap()

  • 特殊的VMA:堆,用于满足进程动态内存请求

    • malloc / free

管理

进程描述符 task_struct 中的mm字段是指向虚拟内存描述符的指针。虚拟内存描述符 mm_struct

  • mmap:指向虚拟内存区域链表的表头,类型是虚拟内存区域描述符 vm_area_struct,映射文件对象 vm_file

  • pgd:指向页目录表

内核空间

内核虚拟内存与物理内存的映射

直接映射区和动态映射区

6.2.2 内存管理

物理内存管理

以页为单位,记录、分配和回收物理内存。物理页框为4KB

页表建立时机:进程页表的构建一直推迟到访问页时才建立。

三个管理区:

  • ZONE_DMA:包含低于16MB的常规内存页框,用于对老式的基于ISA设备的DMA支持

  • ZONE_NORMAL:高于16MB且低于896MB的常规内存页框

  • ZONE_HIGHMEN:从896MB开始的高端物理页框,内核不能直接访问

    • 内核动态映射空间,vmalloc()

    • 永久内核映射

    • 临时内核映射

  • 前两个属于直接映射区,物理地址=虚拟地址-3GB;第三个属于动态映射区,会产生碎片,但带来了很高的灵活性

  • 空闲物理单元

    使用free_area数组记录当前空闲的物理内存单元,每一项描述了一组由相同大小的空闲物理页块构成的双向链表。大小均为2的整数次幂,相邻项相差一倍。

  • 物理页分配

    首先在页块大小相应的空闲页块链中找到一块空间进行分配;如果没有,则在数组下一个元素(更大的空间)中寻找,直到找到能够分配的空间后,把该空间一分为二,一部分分配给进程,另一部分存入数组中

  • 物理页释放

    释放时进行页块合并

使用伙伴(buddy)算法管理连续的空闲页框。适用于大块内存的分配。分配时,若所需空间较小,则将大空间一分为二;否则合二为一。组织成11个(大小从2^0~2^10)的空闲页框链表

内核内存管理

使用Slab算法为小内存区分配。针对内核对象,没有因碎片引起的内存浪费,内核请求可以快速得到满足

Slab是由一个或多个物理上连续的页组成的空间,cache有一个或多个slab,每个内核数据结构都有一个cache,每个cache含有内核数据结构的对象实例。

分配方法:

  • 创建cache时包括标记为空闲的若干对象,对象数量与slab大小相关

  • 当需要内核数据结构对象时,直接从cache获取,并将该对象标记为使用

  • slab分配器首先从部分空闲的slab开始分配

    • 如没有则从空的slab进行分配

    • 如没有空slab则从连续物理块上分配新的slab,并把它赋给一个cache,然后再从新slab分配空间

Linux 内核 | 内存管理——slab 分配器 - 知乎

slab分配器分配内存以字节为单位,基于伙伴分配器的大内存进一步细分成小内存分配。换句话说,slab 分配器仍然从 Buddy 分配器中申请内存,之后自己对申请来的内存细分管理。

除了提供小内存外,slab 分配器的第二个任务是维护常用对象的缓存。对于内核中使用的许多结构,初始化对象所需的时间可等于或超过为其分配空间的成本。当创建一个新的slab 时,许多对象将被打包到其中并使用构造函数(如果有)进行初始化。释放对象后,它会保持其初始化状态,这样可以快速分配对象。

SLAB分配器的最后一项任务是提高CPU硬件缓存的利用率。 如果将对象包装到SLAB中后仍有剩余空间,则将剩余空间用于为SLAB着色。 SLAB着色是一种尝试使不同SLAB中的对象使用CPU硬件缓存中不同行的方案。 通过将对象放置在SLAB中的不同起始偏移处,对象可能会在CPU缓存中使用不同的行,从而有助于确保来自同一SLAB缓存的对象不太可能相互刷新。 通过这种方案,原本被浪费掉的空间可以实现一项新功能。

为什么要分专用和通用 slab ? 最直观的一个原因就是通用 slab 会造成内存浪费:出于 slab 管理的方便,每个 slab 管理的对象大小都是一致的,当我们需要分配一个处于 64-96字节中间大小的对象时,就必须从保存 96字节的 slab 中分配。而对于专用的 slab,其管理的都是同一个结构体实例,申请一个就给一个恰好内存大小的对象,这就可以充分利用空间。

虚拟内存管理(地址转换)

每个进程的4GB虚拟内存分为用户区:0~3GB,和内核区:3~4GB。

在物理内存管理的基础上,使用请求调页机制和交换机制,为系统中每个进程提供高达4GB(i386平台)的虚拟内存空间。

  • 32位机的页表管理

    • 使用二级页表,为每个进程分配一个页目录表

    • 页表推迟到访问页时才建立

    • 页目录表和页表均占10位,页内地址占12位

    • 使用LFU页面置换算法

    • 缺页调入

      • 从未被进程访问过的页,没有相应的内存映射:从指定文件中调页

      • 属于非线性内存映射文件:从磁盘读入

      • 已被进程访问过,其内容被临时保存到磁盘交换区:从交换区调入

      • 在非活动页框链表中:直接使用

      • 正在由其它进程进行IO传输过程:等待传输完成

盘交换区空间管理

每个盘交换区由一组4KB的页槽组成。

  • 第一个页槽存放该交换区的有关信息,有相应的描述符

  • 内核尽量把换出的页存放在相邻页槽中,减少访问交换区时磁盘的寻道时间

6.2.3 文件系统

类型:ext2/ext3/ext4

文件目录是树形(倒树形)结构;把管理的文件看成是无结构的字节流;把外部设备看成与普通文件一样的特殊文件;虚拟文件系统VFS层

ext2文件卷

由若干磁盘块组成,支持1KB、2KB、4KB大小的块,创建文件系统时指定,之后不可修改。每个块内存放一个文件的数据

布局:

  • 1个引导块:第一个盘块,用作引导块(根文件系统)或保留不用

  • n个块组,块组结构如下:

    • 1个超级块:存放整个文件卷的资源管理信息,一个超级块代表一个文件系统实例。只使用块组0中的超级块

    • k个块组描述符:每个占1块,包含了相邻磁道的磁道块。只使用块组0中的块组描述符

    • 1块数据块位图:记录文件数据区各个盘块的使用情况

    • 1个索引节点位图:记录索引节点区各个索引节点的使用情况

    • m个索引节点区:存放文件的索引节点。一个索引节点存放一个文件的管理和控制信息

    • n个文件数据区:存放普通文件和目录文件等

文件目录

树形目录结构。

文件目录项包括两部分:

  • 简单目录项

    • 提高文件目录的检索速度

    • ext2_dir_entry_2,包含:

      • 分配的文件的索引节点号,标记为0表示已被删除

      • 目录项长度,为从该目录项到下一个有效目录项的偏移

      • 文件名长度

      • 文件类型

      • 文件名,长度必须是4字节的整数倍,不足的以'\0'填充

    • 一个目录项至少是12个字节

  • 索引节点

    • ext2_inode,大小为128B

    • 存放文件的管理和控制信息

    • 索引表:三级混合索引

虚拟文件系统

一个通用的文件模型,能够表示其支持的所有文件系统。

使用一组数据结构代表通用文件对象,磁盘不存储,运行时在内存建立。

包含以下4个主要对象:

  • 超级块对象 super_block:代表一个已安装的文件系统,存放该文件系统的管理和控制信息。与超级块关联的方法由超级块操作表描述

  • 索引节点对象 inode:对于具体文件系统,它代表一个物理意义上的文件。

  • 目录项对象 dentry:对应一个目录项,描述文件逻辑属性。目录项在磁盘上没有对应的映像,存放在slab分配器的高速缓冲区中。使用目录项高速缓冲管理目录项对象

  • 文件对象 file:记录进程与打开的文件之间的交互信息,即系统打开文件表。文件对象在磁盘上没有对应的映像。

进程打开文件相关数据结构:task_struct

  • fs_struct:fs字段,描述已安装的文件系统的信息

  • files_struct:即进程打开文件表,files字段,描述当前打开文件信息

文件系统的注册和安装

  • 注册:

    • 分为两步:

      1. 生成一个 file_system_type 类型的结构体,并填写相应内容

      2. 使用模块初始化代码,调用 register_filesystem 函数完成注册

  • 安装:mount命令

    • 根文件系统由系统自动安装,其他文件系统通过调用 mout 函数实现

7 Windows系统

7.1 操作系统模型

7.1.1 体系结构

分为用户态和核心态。

用户态

进程只能运行在受保护的地址空间。

以用户态运行的进程:

  • 系统支持进程

    • idle进程:id为0。每个CPU都有一个相应的线程,用来统计空闲CPU时间

    • 系统进程:包含一个核心态系统线程,id为2,是一个只运行在核心态的系统线程的宿主。负责执行I/O请求、进程换入换出、把内存脏页写入外存

    • 会话管理器SMSS:在系统中创建的第一个用户态进程,负责系统的初始化过程

    • Windows登录进程WINLOGON:处理用户的登录和注销。如果用户合法,该进程将代表用户创建并激活一个登录shell进程

    • 本地安全验证服务器进程LSASS:接收来自登录进程的身份验证请求,执行实际的验证

  • 系统服务进程:系统引导时自动创建、启动

  • 环境子系统进程:Win32、POSIX、OS/2

  • 用户应用程序进程:用户应用进程不能直接调用操作系统服务,所有请求必须由用户态的动态链接库检查合法后,转换成对系统内部相应的API调用

  • 子系统动态链接库:NTDLL.DLL,包括两类函数:

    • 第一类作为Windows执行体系统服务的接口提供给用户态调用时使用

    • 第二类为子系统、子系统动态链接库及其他本机映像使用的内部支持函数

内核态

操作系统服务组件运行在同一的核心地址空间。

操作系统服务组件包括:

  • 执行体:包含了基本的操作系统服务

  • 内核:提供一组严格定义的低级的基本内核对象,以帮助控制、处理和支持执行体对象的创建

    • 被称为“控制对象”的对象集合,用来控制操作系统的各个基本功能,包括:内核进程对象、异步过程调用对象、延迟过程调用对象、几个由I/O系统使用的对象,如中断对象等

    • 被称为“调度程序对象”的对象集合,用来同步进程和线程的操作并影响线程调度,包括:内核线程、互斥体事件、内核事件对、信号量、定时器等

  • 硬件抽象层HAL:直接操纵硬件。是一个可加载的核心态模块HAL.dll

  • 文件和设备驱动程序:可加载的核心态模块,是I/O系统、文件系统和硬件设备之间的接口

  • 窗口和图形:实现了GUI

7.1.2 特点

  • 可移植性:将操作系统的实现机制与策略分离

  • 支持对称多处理和可伸缩性

  • 核心组件使用面向对象的设计原则

    融合了分层模型和客户/服务器等技术的特点

7.1.3 系统机制

  • 陷阱调度

    包括中断、延迟过程调用、异步过程调用、异常调度、系统服务调度。

    • 陷阱处理程序:操作系统用来处理意外事件的硬件机制。当硬件或软件检测到异常或中断发生时,暂停正在处理的事,把控制转交给内核的陷阱处理程序,该模块检测异常和中断的类型,并将控制转交给相应情况的代码

    • 中断调度

      • 类型:硬件中断、软件中断、用户线程

      • 中断优先级:

        • 3~31:为硬件中断保留

        • 2:延迟过程调用DPC,系统范围

        • 1:异步过程调用APC,特定于某个线程

        • 0:普通的线程,允许所有中断发生

        • 1和2是内核和设备驱动器产生的软件中断

    • 异常调度:运行程序直接产生的同步事件。除了那些简单的可由陷阱处理程序解决的异常之外,所有异常都是由内核模块的“异常调度程序”提供服务的

    • 系统服务调度

  • 执行体对象管理器

    通常由代表某个用户应用程序的环境子系统创建,或者由操作系统的各个组件正常操作时创建。

    • 对象:是一种内核结构

    • 对象类型

      • 执行体对象:包含一个或多个内核对象

      • 内核对象:仅供执行体使用,提供基本的能力,如执行体对象之间的同步

    • 对象结构

      • 对象头:包含对所有对象公共的数据,但对于对象的每个实例,其数据的取指可能不同

      • 对象体

    • 对象组织:哈希树

    • 对象名:唯一标识一个对象

    • 对象访问:对象地址/句柄

  • 同步

    • 内核同步:自旋锁,是一个全局数据结构有关的锁定机制

    • 执行体同步:内核以内核对象形式提供的用户态可见的附加的同步机制,即“调度程序对象

      • 类别:进程、线程、事件、信号量、互斥体、可等待的定时器、I/O完成端口、文件等同步对象

      • 对象状态:有信号/无信号

      • 等待对象变为有信号状态:WaitForSingleObject(),传入两个参数:被等待对象句柄、等待时间

  • 本地过程调用

  • 其他:Windows NT全局标志

7.2 进程和线程管理

7.2.1 进程

结构

  • 内核空间:

    • 执行体进程块 EPROCESS,公共的调度程序对象头

    • 内核进程块 KPROCESS

  • 用户空间:进程环境块 PEB

服务

  • CreateProcess:创建进程

  • ExitProcess/TerminateProcess:终止进程。前者终止进程和进程中所有线程的执行,关闭所有打开对象句柄、所有线程等,是正常采用的退出方式;后者不仅可以终止自己,也可以终止其他进程,通常只用于异常情况下使用进程句柄来终止进程。终止操作不完整。

7.2.2 线程

结构

  • 内核空间:

    • 执行体线程块 ETHREAD,公共的调度程序对象头

    • 内核线程块 KTHREAD

  • 用户空间:

    • 线程环境块 TEB

    • 进程环境块 PEB

服务

  • CreateThread

    • 在进程的地址空间为线程创建用户态堆栈

    • 初始化线程的CPU硬件描述表

    • 创建执行体线程对象

  • ExitThread/TerminateThread:终止线程。

    线程的终止有三种方式:

    1. 自然死亡:线程完成函数执行。

    2. 自杀:线程调用ExitThread

    3. 他杀:系统中的某线程调用了TerminateThread

7种状态

  • 就绪:线程在就绪队列牌堆

  • 备用:已选好处理机,正等待描述表切换

  • 运行:只能有一个线程可以处于运行态

  • 等待:等待某个事件或对象变为有信号

  • 传输:核心栈被调到外存

  • 终止:执行完成

  • 初始化:正在创建过程中

 

7.2.3 线程调度

7.2.3.1 单核调度

  • 采用基于可变优先级的、抢占算法调度线程

  • 抢占确保最高优先级的线程总是运行

  • 调度时机

    • 主动切换

    • 抢占

    • 时间配额用完

    • 运行结束

  • 优先级

    • 优先数越大,优先级越高

    • 特殊线程:0

    • 可变类型:1~15

    • 实时类型:16~31

  • Win32 API定义的优先级类型:

    • REALTIME_PRIORITY_CLASS

    • HIGH_PRIORITY_CLASS

    • ABOVE_NORMAL_PRIORITY_CLASS

    • NORMAL_PRIORITY_CLASS

    • BELOW_NORMAL_PRIORITY_CLASS

    • IDLE_PRIORITY_CLASS

  • 相对优先级

    • TIME_CRITICAL

    • HIGHEST

    • ABOVE_NORMAL

    • NORMAL

    • BELOW_NORMAL

    • LOWEST

    • IDLE

每个线程在其所属的类型中有一个基础优先级,一般为NORMAL相对优先级的值。

  • 空闲优先级(4):系统处于空闲状态时执行的程序,如屏幕保护程序

  • 普通优先级(7/9):能升高或降低普通进程优先级

    • 线程时间片用完,降低优先级,但不会降至基础优先级之下

    • 线程从等待操作释放时,调度程序提升其优先级

  • 高优先级(13):只有在需要时才使用,如Task manager以高优先级运行

  • 实时优先级(24):用于核心态系统程序

进程通常属于NORMAL_PRIORITY_CLASS。

7.2.3.2 在SMP上的线程调度

  • 单处理器系统:只有一个单处理器核以及一个CPU

  • 多处理器系统:有多个处理器,每个处理器有一个单核CPU。这些处理器共享计算机总线,有时也会共享时钟、内存、外部设备。

    • 非对称多处理器(Asymmetric MultiProcessing)

      • 每个处理器被分配一个单独的任务

    • 对称多处理器(Symmetric MultiProcessing)

      • 每个处理器都处理所有任务

      • 所有处理器共享系统总线上的物理内存

亲和关系(Affinity):每个线程有一个亲和掩码,描述该线程可在哪些处理机上运行。默认为所有可用处理机的集合

数据结构

  • 32个就绪队列:每个优先级对应一个

  • 32位线程就绪队列位图:每一位指示一个优先级就绪队列中是否有线程等待运行

  • 32位处理机空闲位图:每一位指示一个处理机是否处于空闲状态

处理机

  • 首选处理机

    • 线程运行时偏好的处理机

    • 基于进程控制块的索引值在线程创建时随机选择

  • 第二处理机

    • 线程最近在运行的处理机

多处理机调度算法

  1. 有空闲处理机

    首选处理机→第二处理机→正在运行线程调度程序的处理机→按处理机编号选第一个空闲处理机

  2. 无空闲处理机

    如果可以抢占一个处于运行状态或备用状态的线程,则首选处理机→第二处理机→按处理机掩码选择编号最大的处理机

优先级高的就绪线程可能不处于运行状态。

7.2.4 线程同步

  • 实现线程互斥和同步的机制:

    • 事件对象:有信号/无信号

    • 互斥体对象:控制共享资源的互斥访问

    • 信号量对象:资源信号量,用于限制并发访问资源的线程数

  • 线程同步:

    • WaitForSingleObject()

    • WaitForMultipleObject()

7.3 内存管理

  • 主要分为:页式管理、段式管理、段页式管理

  • 提供基本服务:

    • 存储器管理需要的系统服务

      • 分配、释放、保护虚存和物理主存、写时复制、虚拟页信息等

      • 以Win32 API或核心态设备驱动程序接口形式提供

    • 运行在核心态系统线程上的例程

      • 平衡工作集管理器

        维护空闲主存数量不低于某一界限并及时调整进程的工作集

      • 进程/堆栈交换器

        执行换入/换成操作

      • 更改页写入器

        将脏页(被修改页)写回磁盘

      • 废弃段线程

        高速缓存和页文件的扩大与缩写

      • 零页线程

        维护系统有足够多的零填充的空闲页存在

7.3.1 地址空间布局

在32位的地址空间上,每个进程有4GB的线性虚拟地址空间:

  • 低2GB/3GB为进程的私有空间:每个进程的私有代码和数据

  • 高2GB/1GB为进程公用的操作系统空间:系统范围的代码和数据

Windows企业版有一个引导选项,允许用户拥有3GB的地址空间

7.3.2 私有空间分配

x86模型中,用全局描述符表GDT和局部描述符表LDT分别实现操作系统公共空间和进程私有虚拟地址空间的分配。

私有空间一部分映射到物理内存:使用虚拟地址描述符VAD记录进程空间,一部分映射硬盘上的交换文件:多个进程共享存储区。

  • 虚拟地址描述符 VAD

    • 进程要求分配虚存时,系统并不立即构造页表,而是为其建立一个VAD结构,记录该地址空间的相关信息:

      • 被分配的地址域的起始地址和结束地址

      • 该域是共享的还是私有的

      • 该域的存取保护

      • 是否可继承

    • 页表的构建推迟到访问页时建立

    • 一个进程的一组VAD构成一个自平衡二叉树,便于快速查找

  • 区域对象

    • 文件映射对象,可被多个进程共享的存储区

    • 一个区域对象可被多个进程打开

    • 提高文件访问效率

    • 利用区域对象映射磁盘上的文件,访问这个文件就像访问内存中的一个大数组,而不需要读写操作

      • 执行体利用区域对象将一个可执行的映像装入主存

      • 高速缓冲管理器使用区域对象访问一个被缓冲文件中的数据

      • 进程使用区域对象将一个大于进程地址空间的文件映射到进程整个或部分地址空间中

    • 结构:

      • 对象头

      • 对象体

        • 最大尺寸:区域的最大长度;如果映射一个文件,则为文件大小

          最大尺寸可达2^64 B

        • 页保护方式:创建区域时分配给该区域的所有页的保护方式

        • 页文件(交换区)/映射文件:指出区域是否被创建为空,或是加载一个文件

        • 基准/非基准的:基准则要求共享该区域的所有进程在相同的虚拟地址空间出现

      • 系统提供的对象服务

        • 检索和更改区域对象体中属性

7.3.3 存储空间分配

  • 进程私有地址空间页状态:

    • 空闲的:未被使用

    • 保留的:已预留虚存,未分配物理主存

    • 提交的:已分配物理主存或交换区

  • 分配方法:两阶段分配,先保留地址空间,再提交地址空间的页。也允许保留和提交同时实现

  • 页表建立时机:进程页表的构建一直推迟到访问页时才建立

  • 存储空间管理:使用页框数据库存储页框,每一项记录了相应页框的状态

    • 页框的8个状态:活动、转换、备用、更改不写入、空闲、零初始化、坏的

    • 6个链表:零初始化、空闲、备用、更改、更改不写入、坏的

    • 状态转换:

      • 零初始化/空闲/备用

      • 更改页写入线程,更改→备用

7.3.4 地址变换

一个页大小为4KB

32位地址空间,采用二级页表。地址分为三部分:

  • 页目录索引:占10位

  • 页表索引:10位

  • 页内字节索引:12位

缺页处理

请求调页和“集群”方式

页面置换策略:

  • 多处理机:局部先进先出

  • 单处理机:近似LRU

为每个进程分配一定数量的页框,称为进程工作集。

原型页表项

引入:解决多进程共享页变化对各进程页表的影响

解决方法:在页表和页框数据库之间增加原型页表

7.4 文件系统

FAT和NTFS都以为单位管理磁盘空间。簇的大小是在使用Format命令格式化卷时确定的。

7.4.1 FAT

物理结构:链接

Windows可以支持FAT12、FAT16、FAT32。这里的12、16、32是指描述磁盘块簇地址使用的位数。

7.4.2 NTFS

物理结构:索引

NTFS卷结构由三部分组成:

分区引导扇区

16个扇区,包含卷布局/文件系统结构/引导代码等

主控文件表区 MFT

NTFS卷的管理控制核心,

内容包括:

  • 元数据

    • 系统引导程序

    • 用于定位和恢复卷中所有文件的数据结构

    • 记录整个卷的分配状态的位图

  • 文件/目录信息

结构记录式结构,大小为1KB

  • 记录内容:前16个记录,元数据;其余记录,文件信息

    一个文件/目录信息可能分布在多个MFT记录中,用于存放同一文件属性的第一个记录叫做文件的基记录,其他记录叫做扩展记录

  • 记录结构

    • 记录头

    • (属性,值)

      • 有名/无名属性

        • NTFS负责读取有名属性(文件属性)

        • 应用程序读取无名属性(实际文件数据)

      • 常驻/非常驻属性

        • 小文件:所有属性和属性值常驻内存,放在MFT的一个文件记录中,该属性称为常驻属性

        • 小目录:所有属性常驻内存;索引根属性包含所有文件和子目录的目录项

        • 大文件:分配一个与MFT分开的区域,称为一个运行run或一个扩展extent。每个运行有一个虚拟簇号VCN和逻辑簇号LCN之间的映射和该运行的长度。这个映射信息告诉NTFS组成MFT的运行定位在磁盘上的位置。

        • 大目录:部分索引在索引根属性中,其余索引在索引缓冲区中;索引缓冲区采用B+树实现

MFT实现簇号间的映射:

  • 虚拟簇号VCN:文件中的位置

  • 逻辑簇号LCN:磁盘上的位置

文件数据区

8 复习题

1. 操作系统概论

  1. 早期操作系统设计的主要目标是什么?

    1. 方便性:方便用户使用计算机。用户通过操作系统来使用计算机。

    2. 有效性:使计算机能高效可靠地运转,提高系统资源利用率

    3. 便于操作系统的设计、实现和维护

  2. 操作系统是资源管理程序,它管理系统中的什么资源?

    处理机管理、存储器管理、设备管理、文件管理

  3. 为什么要引入多道程序系统?它有什么特点?

    • 引入:提高CPU利用率,充分发挥系统设备的并行性,包括程序之间、CPU与设备之间、设备于设备之间的并行操作

    • 特点:主存多道,宏观并行,微观串行

  4. 叙述操作系统的基本功能。

    • 处理机管理:解决处理机如何调度的问题:FCFS、优先级、时间片轮转

    • 存储器管理:存储分配、存储保护、存储共享

    • 设备管理:分配设备、控制设备传输数据

    • 文件管理:将程序、数据、操作系统软件等组织成文件,存放在磁盘或磁带上,方便用户访问

  5. 批处理系统、分时系统和实时系统各有什么特点?各适合应用于哪些方面?

    1. 批处理:适合计算量大、自动化程度高的成熟作业

      • 优点:系统吞吐量大、资源利用率高

      • 缺点:用户与作业无法交互,作业平均周转时间较长

    2. 分时系统:适用于短小作业。

      特点:

      • 同时性:若干用户同时使用一台计算机

      • 独立性:每个用户占有一台终端,独立操作,感觉不到别的用户存在

      • 交互性:用户可通过终端与系统进行人机对话

      • 及时性:用户的请求能在较短时间内得到响应

    3. 实时系统:适用于需要计算机能对随机发生的外部事件做出及时的响应和处理

      特点:

      • 实时性响应时间由被控制对象所能承受的延迟来确定

      • 可靠性:要有容错能力,可采用双工机制:一台主机;一台后备机

      • 确定性:系统按照固定的、预先确定的时间执行指定的操作。其可确定性取决于系统响应中断的速度和处理能力。

  6. 操作系统的主要特性有哪些? 

    • 并发性:物质基础是资源共享

    • 共享性:资源可供系统中多个并发执行的进程共同使用。

    • 虚拟性:把共享资源的一个物理实体变为若干个逻辑上的对应物

    • 异步性:有限的资源共享使并发进程之间产生相互制约关系

  7. 衡量 OS 的性能指标有哪些?什么是吞吐量、响应时间和周转时间?

    性能指标:

    • 资源利用率

    • 吞吐量

    • 周转时间

  8. 什么是嵌入式系统?

    以实际应用为中心、以计算机技术为基础、软硬件可裁剪的专用计算机系统。

  9. 什么是对称多处理?它有什么好处?

    对称多处理:操作系统和用户程序可安排在任何一个处理机上运行,各处理机共享主存和各种I/O设备

    优点:

    • 增加了系统的吞吐率

    • 增加了系统的可靠性

  10. 为了实现系统保护,CPU 通常有哪两种工作状态?各种状态下分别执行什么程序?什么时候发生状态转换?状态转换由谁实现?

    • 用户态用户自编程序和系统外层的应用程序

    • 核心态操作系统内核程序

    • 用户态→核心态:硬件完成,中断、异常、系统调用

    • 核心态→用户态:内核程序执行后完成

  11. 什么是系统调用?什么是特权指令?特权指令执行时,CPU 处于哪种工作状态?

    • 系统调用:内核向用户提供的,用来运行系统内核子程序的接口

    • 特权指令:指关系系统全局的指令,如存取和操作 CPU 状态,启动各种外部设备, 设备时钟时间,关中断,清主存,修改存储器管理寄存器,改变用户方式到核心方式和停 机指令等。

    • 特权指令执行时,CPU 处于核心态。

  12. 操作系统通常向用户提供哪几种类型的接口?其主要作用是什么?

    • 操作接口:命令语言或窗口界面,是用户使用计算机系统的主要接口。

    • 编程接口:系统调用,是用户与操作系统之间的编程接口

2~3. 进程管理

  1. 程序顺序执行的特点是什么?

    并发执行

    • 串行性

    • 封闭性:程序在运行时独占全机资源,因此,这些资源的状态只能由该程序决定和改变, 不受外界因素影响。

    • 可再现性:只要初始条件相同,无论程序连续运行,还是断断续续地运行,程序的执行结果不变

  2. 何谓进程?进程由哪些部分组成?试述进程的四大特性(动态性、独立性、并发性、结构性)及进程和程序的区别。

    进程是可用和其他程序并行执行的程序的关于某个数据集合的一次执行过程。

    包括:程序、数据、进程控制块

    • 动态性

    • 独立性

    • 并发性

    • 结构性

  3. 进程控制块的作用是什么?它主要包括哪几部分内容?

  4. 进程的基本状态有哪些?试举出使进程状态发生变化的事件并描绘它的状态转换图。

  5. 什么是原语?什么是进程控制?

  6. 试述进程调度的功能、方式、时机、算法;作业调度,交换调度;作业的周转时间和作业的带权周转时间。

  7. 试述线程的定义,线程与进程的比较,系统对线程的支持(用户级线程、核心级线程、两级组合)。

  8. 并发执行的进程在系统中通常表现为几种关系?各是在什么情况下发生的?

  9. 什么叫临界资源?什么叫临界区?对临界区的使用应符合的四个准则(互斥使用、有空让进、有限等待、让权等待)。

  10. 试述解决进程之间互斥的办法(开、关中断,加锁、开锁(又叫测试与设置, 通常由一条机器指令完成),软件方法,信号量与 P、V 操作)。

  11. 若信号量 S 表示某一类资源,则对 S 执行 P、V 操作的直观含意是什么? 当进程对信号量 S 执行 P、V 操作时,S 的值发生变化,当 S>0、S=0、和 S<0 时, 其物理意义是什么?

  12. 在用 P/V 操作实现进程通信时,应根据什么原则对信号量赋初值?

    • 互斥信号量:初值为1;

    • 同步信号量:初值为资源数量

  13. 掌握经典的 IPC 问题。

  14. 进程高级通信有哪些实现机制?

    • 消息缓冲通信:缓冲池、信箱

    • 共享存储区

    • 管道

  15. 死锁产生的必要条件及解决死锁的方法。 

  16. 理解银行家算法的实质。能够利用银行家算法避免死锁。

4. 存储器管理

  1. 试述存储器管理的功能。什么是名字空间、地址空间、存储空间、逻辑地址、物理地址。

  2. 什么是地址重定位?分为哪两种?各是依据什么和什么时候实现的?试比较它们的优缺点。

  3. 内存划分为两大部分:用户空间和操作系统空间。存储器管理是针对用户空间进行管理的。

  4. 存储保护的目的是什么?对各种存储管理方案实现存储保护时,硬件和软件各需做什么工作?

  5. 试述可变式分区管理空闲区的方法及存储区的保护方式。

    管理方法:分区说明表、空闲区链表

  6. 什么是页式存储器的内零头?它与页的大小有什么关系?可变式分区管理产生什么样的零头(碎片)?

  7. 覆盖与交换有什么特点?

  8. 页表的作用是什么?简述页式管理的地址变换过程。能利用页表实现逻辑地址转换成物理地址。管理内存的数据结构有哪些?

  9. 段式存储器管理与页式管理的主要区别是什么?

    • 段是由用户划分的;页是由硬件划分的

    • 段的大小不固定;页的大小固定

    • 段式用二维地址空间;页式用一维地址空间

    • 段允许动态扩充,便于存储保护和信息共享

    • 段可能产生主存碎片;页消除了碎片

    • 段式管理便于实现动态链接;页式管理只能进行静态链接

  10. 什么是虚拟存储器?虚拟存储器的容量能大于主存容量加辅存容量之和吗?

  11. 实现请求页式管理,需要对页表进行修改,一般要增加状态位、修改位、访问位。试说明它们的作用。

  12. 产生缺页中断时,系统应做哪些工作?

    寻找空闲页框;装入或替换;恢复现场

  13. 会利用 FIFO、LRU、OPT 以及时钟页面置换算法描述页面置换过程,计算产生的缺页率。了解 Belady 异常。

  14. 什么是程序的局部性原理?什么叫系统抖动?工作集模型如何防止系统抖动?

  15. 掌握多级页表的概念,多级页表中页表建立的时机,以及写时复制技术的概念。

    写时复制技术:若没有进程向共享主存页写时,两个进程就共享之。若有进程要写某页, 系统就把此页复制到主存的另一个页框中,并更新该进程的页表,使之指 向此复制的页框,且设置该页为可读/写。

  16. 掌握页的共享。需要一个专门数据结构来记录进程间共享页。

5. 文件系统

  1. 什么是文件和文件系统?文件系统的主要功能是什么。UNIX 系统如何对文件进行分类?它有什么好处?

  2. 文件目录的作用是什么?文件目录项通常包含哪些内容?文件控制块是什么?

  3. 文件的逻辑结构有几种形式?文件的存取方法有哪几种?

  4. 文件的物理结构有哪几种?对于不同的结构,文件系统是如何进行管理的? 

  5. DOS 文件卷的结构是什么? DOS 系统的文件物理结构是什么?

  6. 了解记录的组块和分解。

  7. 文件存储空间的管理方法有几种?它们各是如何实现文件存储空间的分配和回收的?

  8. 建立多级目录有哪些好处?文件的重名和共享问题是如何得到解决的?

  9. 文件系统中,常用的文件操作命令有哪些?它们的具体功能是什么?打开和关闭文件命令的目的是什么?

  10. 存取控制表 ACL 的概念。

  11. 理解内存映射文件(memory mapped file)的过程。

    将文件映射到进程地址空间的一个区域返回虚拟地址,仅当需要对文件进行存取时,才传输实际的数据。使用与请求页式虚存管理相同的存取机制访问的页不在主存时,产生缺页中断读入主存。OS提供映射文件的系统调用。

6. 设备管理

  1. I/O 设备通常大致可分为哪两大类?各自传输的信息单位有什么特点?

    • 字符设备

    • 块设备

  2. 掌握常用的四种数据传输方式。

    • 查询

    • 中断

    • DMA

    • 通道

  3. 根据设备的使用方式,设备被分为几种类型?何为虚拟设备?它是通过什么技术实现的?

    • 独占设备

    • 共享设备

    • 虚拟设备

  4. 按照设备管理的层次结构,I/O 软件划分为几层?各层主要实现哪些功能?

    • 用户层I/O接口

    • 设备独立软件

      • 基本任务:实现所有设备都需要的功能,且向用户ᨀ供一个统一的接口。

      • 设备命名

      • 设备保护

      • 提供与设备无关的块尺寸

      • 缓冲技术

      • 负责设备分配和调度

      • 出错处理

    • 设备驱动程序

    • 中断处理程序

  5. 何为设备的独立性?

    设备独立性是指用户及用户程序不受系统配置的设备类型和具体设备的台号的影响。用户只是使用逻辑设备,具体的映射由操作系统完成。

  6. 什么是 SPOOLING 技术?以输出为例,说明它的实现原理。

    SPOOLING 技术是以空间换时间

  7. 一个特定磁盘上的信息如何进行编址?

    盘面号、磁道号和扇区号(或柱面号、磁头号和扇区号)。

  8. 要将磁盘上一个块的信息传输到主存需要系统花费哪些时间?

    寻道时间+旋转延迟时间+读/写传输时间

  9. 常用的磁盘调度算法

    先来先服务、最短寻道时间优先、扫描法(SCAN, C_SCAN, LOOK, C_LOOK)。

7. Linux 进程管理

  1. 进程控制块,其中与进程管理、存储器管理和文件管理有关的一些字段,线程组标识符。

  2. 与进程创建有关的函数

    • fork( ):子程序采用写时复制技术读共享父进程的全部地址空间。

    • vfork( ):为了防止父进程重写子进程需要的数据,先阻塞父进程的执行

    • clone( )

  3. 理解进程切换的过程。涉及到页目录表、核心栈、硬件上下文。

  4. 进程调度方式。进程调度时机。

  5. Linux 有很多内核线程,了解 0 号进程和 1 号进程的作用。

8. Linux 存储器管理

  1. 进程地址空间的划分?管理进程私有地址空间的数据结构?链接虚拟内存区域的单链表和红黑树。指向映射文件对象的指针字段?指向进程页目录表的指针字段?

  2. Linux 堆的管理:malloc( ),free( )。

  3. 管理物理内存页框的数据结构?内存管理区 zone 结构,伙伴系统?分区页框分配器分配页框的过程。

  4. 理解 slab 分配器的原理。slab 分配器的作用?

  5. 进程页表建立的时机?了解页目录表项或页表项所包含的字段。逻辑地址的划分,利用两级页表实现地址转换的过程。

  6. 请求调页。所缺的页可能存放的地方。

  7. 了解盘交换区空间的管理方法。

9~10. Linux 文件系统

  1. Ext2 文件卷的布局?各部分的作用是什么?

  2. Linux 系统把一般的文件目录项分成哪两部分?这样做的好处是什么?

    简单目录项、索引节点

  3. Linux 文件系统的索引节点中,索引表划分成几级?计算文件最大长度。文件的索引表是如何增长的?要求能够利用索引表实现将文件中的字节地址转换成文件的物理块的操作。

  4. 硬链接和符号链接的区别?

  5. Linux 文件系统如何管理空闲存储空间?

  6. VFS 通用文件模型中的四个主要对象?

    • 超级块对象

    • 索引节点对象

    • 目录项对象

    • 文件对象

  7. Linux 系统中,进程打开一个磁盘文件要涉及哪些数据结构?它们各有哪些关键字段?它们的作用是什么?(参考图 10.2)

  8. 一个文件在使用与不用时各占用系统哪些资源?

  9. 安装表的作用是什么?

    将文件系统安装到系统文件目录下。

14. Windows 2000/XP 模型

  1. Windows 采用什么样的体系结构?

  2. 硬件抽象层 HAL 的作用是什么?

  3. Windows 系统组件的基本机制。

    • 陷阱调度

    • 执行体对象管理器

    • 同步(自旋锁、内核调度程序对象)

    • 本地过程调用 LPC

    • 其他

  4. 理解:延迟过程调用 DPC,异步过程调用 APC

  5. Windows 中有哪些对象,都有什么作用?

    两种类型对象:执行体对象和内核对象。执行体组件:进程和线程管理器、内存管理器、I/O 管理器、对象管理器等。内核对象是由内核实现的一个初级对象集,对用户态代码不可见,仅供执行体使用。一个执行体对象可以包含一个或多个内核对象。

  6. 在多处理机系统中,提供了哪些同步和互斥机制?

    内核引入自旋锁实现多处理机互斥机制。内核以内核对象的形式给执行体提供其他的同步机构——“调度程序对象”,包括:进程对象、线程对象、事件对象、信号量对象、互斥体对象、可等待的定时器对象及文件对象等。每个同步对象都有“有信号”或“无信 号”两种状态。

  7. 线程如何实现等待一个同步对象的操作?

15. Windows 进程和线程管理

  1. 管理进程和线程的数据结构:

    执行体进程块 EPROCESS、执行体线程块 ETHREAD、内核进程块 KPROCESS、内核线程块 KTHREAD。

  2. 创建进程:CreateProcess( );创建线程:CreateThread( )

  3. 线程的 7 种状态,及其解释。

  4. 线程调度:

    基于优先级的抢先式的多处理机调度系统。线程调度程序的数据结构:32 个就绪线程队列、32 位线程就绪队列位图、32 位处理机空闲位图。

  5. 线程优先级的提升时机。

    • I/O 操作完成后的线程

    • 信号量或事件等待结束的线程

    • 前台进程中的线程完成一个等待操作

    • 由于窗口活动而唤醒图形用户接口线程

    • 线程处于就绪状态超过一定时间,仍未能进入运行状态(处理器饥饿)

16. Windows 存储器管理

  1. 两种数据结构:虚拟地址描述符 VAD、区域对象,这两种结构各有什么作用?

  2. 虚拟内存区域:空闲的、保留的、提交的。

  3. 32 位逻辑地址,二级页表。页目录表项和页表项具有相同的数据结构,该数据结构包含哪些数据项?进程页表建立的时机。进程的地址转换过程。

  4. 管理物理内存的数据结构:页框数据库。页框的 8 种状态:活动、转换、备用、 更改、更改不写入、空闲、零初始化、坏,页框的状态转换图 16.9。

  5. 原型页表项,区域对象的页表。虚拟页式中,采用原型页表实现多进程共享页。

  6. Windows 采用的页替换策略是什么?

17. Windows 文件系统

  1. Windows 所支持的文件系统类型有哪些?

  2. 虚拟簇号和逻辑簇号的概念。

    • 逻辑簇号:硬件上的簇的编号

    • 虚拟簇号:进程虚拟内存空间的编号

  3. NTFS 卷的结构,主控文件表 MFT 的作用。

  4. NTFS 文件的物理结构:索引顺序结构。

  5. 管理文件的目录结构采用 B-树。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

操作系统笔记(本科必修课) 的相关文章

  • Java——泛型和Io流

    目录 1 泛型 2 File对象 3 IO流 4 字节输入和输出流 5 缓存流 6 对象流 1泛型 1 1什么是泛型 1 泛型就是限制我们得数据类型 2 为什么使用泛型 我们原来在定义集合时 xff0c 是如下得定义方式 xff1a Lis
  • Spring框架入门学习笔记

    Spring概述 目录 Spring概述 IOC容器 概念 底层原理 Spring提供IOC容器实现两种方式 基于xml方式实现属性注入和对象创建 属性注入 xml注入集合属性 Spring中的bean类型 bean的作用域 bean的生命
  • &和&&的区别?

    amp 和 amp amp 都是Java中的逻辑运算符 xff0c 用于对两个布尔值进行逻辑运算 xff0c 但它们有着不同的特点和使用场景 xff0c 具体区别如下 xff1a 1 运算规则 amp 是按位与运算符 xff0c 它会对两个
  • MAC电脑GOland2022.2.1版本DEBUG问题

    在使用goland使用debug调试代码出现 API server listening at 127 0 0 1 56871 could not launch process debugserver or lldb server not f
  • Maven连接数据库

    1 创建一个maven项目 2 在resources中创建db properties配置文件和log4j properties日志的配置文件 db username 61 root db password 61 root db url 61
  • 关于vs2019网络问题解决方案

    首先将IPV4 的DNS设置为默认的114 114 114 114 xff0c 备用DNS为8 8 8 8 xff0c 若没有用 xff0c 则不勾选IPV6 xff0c 亲测有效 这个问题曾经也困扰了我好几个月 xff0c 甚至都想换掉v
  • Spring Boot启动器

    文章目录 Spring Boot启动器简介自定义springboot启动器命名规约自定义starter步骤1 创建一个Spring boot项目2 导入pom3 编写配置类4 在resources META INF目录下新建spring f
  • web开发入门

    在vscode中输入英文 xff0c 按tab键 xff0c 叩可显示html5的框架 搭建好框架之后 xff0c 再进行局部设计即可制作一张简易静态网页
  • springboot学习笔记

    http t csdn cn aLaeJ
  • spring中的annotation简介

    1 注解介绍 注解 xff0c 是一种用来描述数据的数据 比如说 64 override表示我们重载父类函数 如果我们不用这个注解 xff0c 程序也能执行 xff0c 但是我们加了这个注解代表我告诉编译器这个方法是一个重写的方法 如果父类
  • C语言中如何使用字符数组和字符型指针变量

    案例一 使用字符数组统计字符串的长度以及实现字符串的反转 参考代码 xff1a include lt stdio h gt include lt stdlib h gt include lt string h gt int main cha
  • 拓扑排序详解

    提示 xff1a 古人学问无遗力 少壮功夫老始成 xff0c 纸上得来终觉浅 觉知此事须躬行 文章目录 一 AOV网的特点二 问题三 拓扑排序四 拓扑排序的方法五 检查AOV网中是否存在一个环六 两种思路6 1 思路一6 1 1 思路一代码
  • Altium Designer——设置电源线规则

    1 创建类来新建规则 执行菜单Design Classes 快捷键DC 将这多个网络建立一个class 执行菜单命令Design Rules 快捷键DR xff09 xff0c 进入规则设置栏 xff1b 新建个线宽规则 xff0c 在规则
  • 【Archlinux】(3) —— dwm+st+firefox+fcitx=愉快上网

    Archlinux dwm 43 st 43 firefox 43 fcitx 61 愉快上网 1 dwm窗口管理器2 ST简单终端3 firefox浏览器4 fcitx中文输入法参考资料 注意 后的命令是root用户和普通用户均可以的操作

随机推荐

  • idea创建maven项目产生卡死问题

    2021版idea创建maven项目时卡死问题解决 xff1a 问题描述 xff1a 在file project structure中新建maven的modules时 xff0c 点击finish后idea会卡死 xff0c 其他人有的说要
  • SpringBoot配置环境

    typora copy images to upload 微服务架构 第一个Spring Boot程序 jdk 1 8maven 3 6 1springboot 最新版IDEA 修改端口号 banner banner在线制作网站 Sprin
  • 【坑】导入项目报错Could not find com.android.tools.build:gradle:7.4.0

    报错的图没得了 xff0c 反正就是Could not find com android tools build gradle 7 4 0 这个报错解决思路 xff1a 1 首先导入项目你不要直接File Open xff0c 你要FIle
  • 通过adb命令安装卸载apk

    一 安装apk xff1a 1 正常安装APK adb install xxxx apk 2 覆盖安装APK adb install r xxxx apk 2 安装测试APK adb install t xxxx apk 3 组合使用 ad
  • 使用VNC远程连接云服务器,连接超时问题

    这里用的本地VNC工具为VNC viewer xff0c 使用的服务器为腾讯云CentOS服务器 已经在服务器端完成了图形化界面的安装以及开启vncserver xff0c 但是无法连接 已经创建完成vnc的服务器端 开启vnc命令 vnc
  • Spring框架的知识整理(项目流程)以及SSM框架的整合

    前言 上一篇文章我们发表Mybatis框架的学习心得 xff0c 以及针对一个项目而言说了一些流程 Spring学习的时候我们需要知道它的两个核心功能Ioc Aop xff0c 本文今日对Ioc做重点解释 Ioc功能阐述 Ioc 主要是一个
  • Ubuntu安装文件

    安装Java 首先在官网下载linux版本的jdk 然后传给linux xff0c 在解压到 usr local目录下 xff0c 在进入 url local目录 xff0c 并完成环境配置 tar zxvf jdk 8u331 linux
  • 快速排序(java实现)

    快速排序的思想 在一个无序的数组中 xff0c 取最后的一个数字为基准值 xff0c 在经过一次排序后 xff0c 使得改无效而的数组中 xff0c 小于基准值的在左侧 xff0c 等于基准值的在中间 xff0c 大于基准值的在右侧 假设一
  • 使用websocket实现服务端主动发送消息到客户端

    平时我们都是由客户端浏览器主动发送请求到服务端 xff0c 然后服务器处理请求后返回结果 xff0c 服务器无法主动向客户端浏览器发送消息 但是在某些业务场景下我们需要由服务器主动发送消息到客户端浏览器 xff0c 如当客户用户下订单后 x
  • Day01-Vue的基本格式

    创建Vue实例传入的options 我们在创建Vue的时候 xff0c 会传入一个对象options 这个options包含哪些选项 xff1f 目前掌握这些选项 el 类型 xff1a string HTMLElement xff08 表
  • LAMP架构超详细搭建步骤

    LAMP介绍 xff1a Linux 43 Apache 43 Mysql MariaDB 43 Perl PHP Python一组常用来搭建或者服务器的开源软件 xff0c 本身都是各自独立的程序 xff0c 但是因为常被放在一起使用 x
  • ViewBinding的简单使用

    我们知道ButterKnife已经过时 首先开启viewBinding xff1a android viewBinding enabled 61 true 之后在Activity中操作 span class token keyword pa
  • linux系统下防火墙的使用以及开通端口

    1 基本使用 启动 xff1a systemctl start firewalld 关闭 xff1a systemctl stop firewalld 查看状态 xff1a systemctl status firewalld 开机禁用 x
  • 如何让自己电脑的cmd看起来更美观

    一 快速切换cmd字体颜色 xff08 暂时性 xff09 打开cmd输入color 02 二 永久性切换cmd文字颜色 打开cmd xff0c 在标题栏处鼠标右键选择属性 选择颜色 xff0c 切换自己喜欢的颜色 xff0c 点击确定即可
  • Android 音频开发——Radio Hal服务(三)

    nbsp nbsp nbsp nbsp nbsp nbsp nbsp 上一篇文章主要介绍了 BroadcastRadioService 的启动 这一篇我们介绍以下Radio Hal 层的服务 一 Radio模块的加载 nbsp nbsp n
  • java锁策略和synchronized锁机制

    一 常见的锁策略 1 乐观锁 vs 悲观锁 锁的实现者 xff0c 预测接下来的锁冲突概率大不大 xff0c 根据这个概率决定接下来该做什么 乐观锁 xff1a 预测冲突不大 xff0c 做的工作少一些 xff0c 效率更高一些 悲观锁 x
  • 【蓝桥杯java-学习笔记】单词中出现次数最多的字母和次数

    字符串 输入描述 输入一行包含一个单词 xff0c 单词只由小写英文字母组成 hello 输出描述 输出两行 xff0c 第一行包含一个英文字母 xff0c 表示单词中出现得最多的字母是哪 个 如果有多个字母出现的次数相等 xff0c 输出
  • 解决Use ‘docker scan‘ to run Snyk tests against images to find vulnerabilities and learn how to fix

    解决方法 在终端输入 xff1a sudo export DOCKER SCAN SUGGEST 61 false
  • 子集全排列组合数问题(带你轻松拿捏十一道OJ题)

    目录 一 子集 二 子集II 三 全排列 四 全排列II 五 字符全排列 六 字符串大小全排列 七 组合总和 八 组合总和II 九 组合总和III 十 组合总和IV 十一 递增子序列 一 子集 剑指 Offer II 079 所有子集 力扣
  • 操作系统笔记(本科必修课)

    1 操作系统概论 1 1 定义 操作系统是计算机系统中的一个系统软件 xff0c 是一些程序模块的集合 能以尽量有效 合理的方式组织和管理计算机的软 硬件资源 xff0c 合理的组织计算机的工作流程 xff0c 控制程序的执行并向用户提供各