A-level 计算机/CIE/高级理论/系统软件
规范链接 操作系统的目的
虚拟机
翻译软件
|
操作系统管理三大资源:CPU、内存和输入/输出 (I/O) 系统。I/O 的访问时间明显更长,因此操作系统必须平衡这些资源的使用,以确保 CPU 在等待 I/O 完成时不会处于闲置状态。
用户界面是用户与计算机和操作系统的交互方式。操作系统主要有两种类型:命令行界面 (CLI) 和图形用户界面 (GUI)。
命令行界面是纯文本界面,在 20 世纪 90 年代之前很常见。为了使用 CLI,用户需要知道执行所需操作的命令,这会导致用户体验不够直观。
图形用户界面是一种更直观的界面。GUI 通常包含 Windows、Icons、Menus 和 Pointers 系统。GUI 通常被认为比 CLI 更直观和用户友好。
进程是指存储在内存中当前正在执行或等待执行的程序。进程由进程控制块 (PCB) 控制。
PCB 会跟踪以下信息
- 进程 ID
- 进程的唯一标识符。
- 状态
- 进程是否正在运行、就绪或阻塞。
- 权限
- 进程可以访问哪些数据、内存和系统功能。
- 寄存器状态
- 进程执行时 CPU 中每个寄存器的值。
- 优先级
- 进程在调度算法中是否足够重要以获得优先级。
- 内存信息
- 分配给进程的内存量。
- I/O 信息
- 与进程关联的 I/O 设备列表。
线程是指正在执行的进程的一部分。进程可以是单线程或多线程。多线程进程通常更有效地执行,因为不同的线程可以独立运行。
线程可以在用户级或内核级运行。用户级线程在用户级调度,因此内核不参与线程调度。内核级线程在内核级调度,这使得访问特权系统功能更加容易。
调度是指按照最佳利用资源的顺序,分配给每个进程的执行时间。调度算法是用于确定哪些进程按什么顺序运行的算法。
每个进程都处于三种状态之一:就绪、运行或阻塞。一次只能有一个进程处于运行状态。新进程始终从就绪状态开始。
为了说明调度算法,我们将使用多个进程运行的示例。第一个进程 A 需要 10 个周期,第二个进程 B 需要 15 个周期,第三个进程 C 需要 5 个周期。B 和 C 在 A 之后到达。
先来先服务 (FCFS) 是一种调度算法,进程按其到达就绪队列的顺序执行。
在本例中,这意味着先执行进程 A,然后执行进程 B,最后执行进程 C。
最短作业优先 (SJF) 是一种调度算法,它优先考虑队列中最短的作业。
在示例中,进程 A 仍然会先执行,因为 B 和 C 尚未到达,但它将随后执行进程 C,然后是进程 B。
轮询 算法以重复的顺序为每个进程分配每个时间片。
在时间片长度为 5 个周期的示例中,时间片将依次分配给 A、B、C、A、B、B。
在最高响应比优先 调度算法中,操作系统选择具有最高响应比 的进程。响应比定义为 ,其中W是进程等待的时间,S是进程运行所需的时间。
基于优先级 的调度算法根据优先级标准选择下一个要执行的进程。如果一个进程更重要,它将被更早地执行。
中断 是发送给操作系统的信号,指示它停止当前进程并专注于不同的任务。
中断用于在抢占式调度算法中强制执行时间片。
操作系统不仅负责确定如何分配进程的时间,还负责确定如何分配进程的内存。因此,操作系统需要某种方法来确定如何在进程之间分配内存。
动态分区 是将主内存分割成连续的块,这些块的大小恰好适合进程。这样做的好处是可以避免内部碎片,但会导致外部碎片。
分页 是操作系统将内存划分成大小相等的页面。每个进程使用这些页面中的特定数量。
分页的优点是可以与虚拟内存一起使用,以增加在给定时间可用的内存量。为此,主内存被划分成称为页面帧 的页面大小的空间。页面可以从磁盘加载到这些页面帧中。当一个进程完成或未执行时,页面可以加载回磁盘。
为了确保页面有效地进出内存,需要使用页面替换算法。一个常见的页面替换算法是将最不常使用的页面放回磁盘,以腾出空间用于新页面。
分段 与分页类似,但内存被分成大小不固定、而是可变的块。每个段映射到主内存的一部分,类似于分页系统中页面如何映射到页面帧的方式。
虚拟内存 是使用分页来扩展可用内存量的地方。在虚拟内存系统中,页面根据需要进出主内存。页面被赋予逻辑地址,这些地址使用页面映射 映射到页面帧。
虚拟内存的主要问题是它会导致磁盘抖动。磁盘抖动是指页面太频繁地进出磁盘,这可能会损坏磁盘。
虚拟机 是一种在不同操作系统中模拟操作系统或进程的方式。为此,主机 操作系统与虚拟机交互,而用户与主机操作系统交互。
虚拟机可以是系统 虚拟机或进程 虚拟机。系统虚拟机模拟整个操作系统,而进程虚拟机模拟在不同操作系统中运行的程序。进程虚拟机可以在系统虚拟机中运行。
编译器 是一个程序,它将程序源代码转换为可执行文件,然后可以分发。
解释器 是一个程序,它逐行读取源代码并执行它,而不生成可执行文件。
汇编器 是一个程序,它将汇编代码转换为可执行文件。
词法分析是将源代码分解为其词素的过程。 词素是在程序中出现的单词或符号。
例如,x = y + 1
包含五个词素:x
、=
、y
、+
和1
。
词法分析还检查每个词素是什么类型的标记。 标记可以是以下类型
- 标识符
- 一个变量,例如
x
。 - 关键字
- 用于控制程序的单词,例如
if
或while
。 关键字不能用作标识符。 - 运算符
- 作用于变量的符号,例如
+
和=
。 - 字面量
- 程序中使用的字面量值,例如
"Hello"
或1
。 - 分隔符
- 将一个语句与另一个语句分隔开来的符号,例如分号或换行符。
- 注释
- 程序员用来阐明代码作用的注释。 注释被编译器忽略。
词法分析的最终目标是生成一个标记列表,这些标记可以在语法分析中解析。
例如,代码x = y + 1
可以通过词法分析转换为[(identifier,x),(operator,=),(identifier,y),(operator,+),(literal,1)]
。 然后,这个标记数组由语法分析进行解析。
语法分析是将词法分析中得到的标记串转换为解析树的过程。 解析树是一种数据结构,它根据优先级规则存储标记。
优先级规则,也称为运算顺序,决定表达式中哪些运算先应用。 例如,乘法在加法之前应用。
完整的运算顺序通常类似于此
- 函数调用、数组访问、字段访问
- 一元运算符
- 乘法和除法
- 加法和减法
- 比较
- 按位与、异或,然后是或
- 逻辑与,然后是或
- 赋值
由于优先级较低的运算符后应用,因此优先级较高的运算符往往位于解析树的底部。
巴科斯范式是一种表达编程语言语法的形式。 BNF 使用占位符和备选方案系统来实现这一点。
每个占位符被定义为包含几个备选方案之一。 符号::=
表示“被定义为”。 符号|
表示“或”。
例如,以下 BNF 定义可以根据右侧的语法图构建。
<digit> ::= 0|1|2|3|4|5|6|7|8|9 <variable> ::= x|y|z <constant> ::= <digit>|<constant><digit> <factor> ::= <constant>|<variable>|(<expression>) <term> ::= <factor>|<term>*<factor> <expression> ::= <term>|<expression>+<term>
请注意,一些定义,例如<constant>
的定义,是递归的。 这很有用,因为它允许我们创建可能无限长的常量。
使用 BNF 相对于语法图的优势在于,BNF 可以输入到计算机中并被计算机解释,而语法图不能以相同的方式解释。
优化是使代码更高效的过程。 这意味着删除不必要的步骤并改写复杂的表达式。
例如,表达式z = x^2 + 2*x*y + y^2
可以简化为z = (x+y)^2
优化通常在编译器的后端完成,因为它将程序转换为汇编代码,然后转换为可执行文件。
优化有益,因为
- 它减少了程序运行所需的时间。
- 它减少了程序在内存中占用的空间。
逆波兰表示法是一种表示表达式的形式,使得使用堆栈更容易地对其进行求值。 它与更常见的中缀表示法形成对比。
在中缀表示法中,操作数放置在运算符的两侧,运算符夹在它们之间。(例如,2+2
) 而在 RPN 中,操作数先写,运算符放在最后。(例如,2 2 +
)
要将表达式,例如(2+x)^(3-y)
,转换为 RPN,可以制作一个解析树。
使用堆栈评估 RPN 表达式时,我们需要遵循一些规则
- 当遇到变量或数字时,我们将它的值压入堆栈。
- 当遇到运算符时,我们从堆栈中弹出顶部的值,然后将运算符应用于它们。
- 当评估完成时,堆栈中应该剩下一个项目,即答案。