操作系统的运行环境:包括操作系统与硬件之间的交互方式、操作系统如何管理和调度进程、内存管理、文件系统管理等。
运行机制:涉及操作系统的核心功能和实现原理,如进程管理(进程调度、进程同步与通信)、内存管理(虚拟内存、页面置换算法)、文件系统管理(文件存储与访问)、设备管理等。
第一节 计算机系统的层次结构
各层次的功能和作用
讨论操作系统运行环境与运行机制时,会涉及计算机系统的层次结构。这个层次结构帮助理解计算机系统是如何组织和工作的,从硬件层到操作系统层再到应用层的不同部分。
计算机系统的层次结构可以分为以下几个层次,每个层次都有其特定的功能和作用:
- 硬件层(Hardware Layer):
- 这是计算机系统的最底层,包括CPU、内存、硬盘、输入输出设备(如键盘、鼠标、显示器)、总线等硬件组件。
- 硬件层提供了基本的计算和数据存储能力,但缺乏直接面向用户的功能。
- 操作系统层(Operating System Layer):
- 操作系统位于硬件层之上,是硬件和应用软件之间的中介。
- 它负责管理和控制计算机系统的硬件资源,提供各种服务,如进程管理、内存管理、文件系统管理、设备驱动程序等。
- 操作系统使得多个应用程序能够共享硬件资源,并提供了用户接口,使用户能够方便地与计算机进行交互。
- 应用层(Application Layer):
- 应用层是用户直接接触的部分,包括各种应用程序和用户界面。
- 应用程序利用操作系统提供的服务和资源来完成特定的任务,如文档编辑、图像处理、网络通信等。
计算机系统的层次结构示意图
+-------------------------+
| 应用层 |
| (Applications Layer) |
+-------------------------+
| 操作系统层 |
| (Operating System Layer)|
+-------------------------+
| 硬件层 |
| (Hardware Layer) |
+-------------------------+
操作系统在计算机系统层次结构中的角色
操作系统作为计算机系统的核心组件,承担着多项重要任务:
- 资源管理:管理和分配CPU、内存、存储器等硬件资源,以便多个应用程序能够同时运行并共享资源。
- 提供抽象接口:为应用程序提供抽象的硬件访问接口,简化了程序员对硬件的直接操作,提高了软件的可移植性和可维护性。
- 提供服务:提供各种系统服务,如文件管理、进程管理、安全管理、网络通信等,为应用程序提供必要的支持和环境。
第二节 中央处理器
CPU是计算机系统的核心,负责执行指令、处理数据以及控制整个系统的运行。CPU作为操作系统和应用程序之间的桥梁和执行者,其性能和效率直接影响到系统的整体表现和用户体验。
中央处理器(CPU)的功能
- 指令执行:
- CPU执行存储在内存中的指令序列,这些指令控制计算机的操作,包括算术运算、逻辑运算、数据移动等。
- 时钟和时序控制:
- CPU通过时钟信号同步操作,每个时钟周期执行一条指令或一部分指令,确保系统的稳定运行和正确同步。
- 寄存器:
- CPU内部包含多个寄存器,如数据寄存器(用于存放数据)、地址寄存器(存放内存地址)、指令寄存器(存放当前正在执行的指令)等,这些寄存器在指令执行过程中起到临时存储和传递数据的作用。
- 中断和异常处理:
- CPU能够响应外部设备的中断请求,中断当前执行的程序,执行特定的中断处理程序。异常处理与中断类似,用于处理运行时错误或异常情况。
- 多核处理器:
- 现代计算机系统通常包含多核处理器,每个核心都是一个独立的CPU,能够并行执行多个任务,提高系统的处理能力和性能。
处理器相关的概念
处理器是计算机系统的核心部件,负责执行程序指令。其构成包括ALU、控制单元CU、寄存器、缓存和总线接口单元。
处理器一般由运算器、控制器、一系列的寄存器以及高速缓存构成。
处理器(CPU)的核心部件包括:
- 算术逻辑单元(ALU, Arithmetic Logic Unit):负责执行算术和逻辑运算。
- 控制单元(CU, Control Unit):负责从内存中获取指令,解释指令,并控制指令的执行过程。
- 寄存器(Registers):处理器内部的高速存储单元,用于存储临时数据和指令。
- 缓存(Cache):处理器内部或与处理器紧密连接的高速存储器,用于减少访问主存的时间。
- 总线接口单元(Bus Interface Unit, BIU):负责处理器与系统总线之间的数据传输。
寄存器
是什么?
寄存器(Register)是CPU内部用来存放数据、指令和地址的小型高速存储器。它与CPU的运算逻辑单元(ALU)和控制单元(CU)密切配合,共同完成CPU的基本功能。
寄存器的特点是:
- 访问速度快:寄存器是CPU内部的存储器,因此访问速度远高于内存。
- 存储容量小:寄存器的存储容量通常只有几字节到几十字节,这是为了兼顾速度和成本。
- 用途广泛:寄存器可以存储各种类型的数据,例如整数、浮点数、字符、地址和指令。
寄存器在CPU中起着重要的作用,主要用于以下几种目的:
- 存放指令:CPU从内存中取出的指令首先要存放在指令寄存器中,然后由指令译码器进行译码。
- 存放数据:CPU在运算过程中需要对数据进行读写,这些数据通常存放在通用寄存器或专用寄存器中。
- 存储地址:CPU需要访问内存中的数据或指令,这些数据的地址通常存放在地址寄存器中。
- 控制CPU状态:CPU的状态信息通常存放在状态寄存器中,例如程序计数器、堆栈指针、中断标志等。
一颗CPU中到底存在多少个寄存器?
这个问题没有一个确切的答案,因为不同架构的CPU的寄存器数量和类型有所不同。例如:
- x86架构的CPU:通用寄存器数量为8个(EAX、EBX、ECX、EDX、ESI、EDI、ESP、EBP),专用寄存器数量为13个(CS、DS、ES、FS、GS、SS、IP、PC、FLAGS、MXCSR、XCR0、MSR)。
- ARM架构的CPU:通用寄存器数量为31个(R0~R30),专用寄存器数量为20多个(SP、PC、LR、XPSR、CPSR、MSP、BASE、END、FPSCR、CPSR_FIQ、CPSR_IRQ、DBGBASE、DBGBEND、ITSTATE、ITCSTATE、DCCSW、DCCSW_IT、DCCSW_NMI、SCTLR、AIRCR、VCRMD、VCMR_ALL、SCTLR_BASE、SCTLR_EL1、SCTLR_EL2、SCTLR_EL3)。
总的来说,现代CPU的寄存器数量通常在几十个到几百个之间。寄存器的数量和类型是衡量CPU性能的重要指标之一。一般来说,寄存器越多、位数越高,CPU的性能就越强。
以下是一些具体的例子:
- Intel Core i9-13900K:这颗CPU拥有68个通用寄存器和16个专用寄存器。
- AMD Ryzen 9 7950X:这颗CPU拥有68个通用寄存器和16个专用寄存器。
- Apple M2:这颗CPU拥有32个通用寄存器和12个专用寄存器。
随着CPU架构技术的不断发展,寄存器的数量和功能也在不断完善。这将进一步提高CPU的性能和效率。
寄存器的容量?
一个寄存器最多能存储的数据量取决于寄存器的位数。位数是指寄存器能够存储的二进制位数。例如,一个8位寄存器可以存储个不同的二进制数,每个二进制数由8位组成。
以下是常见寄存器位数及其最大存储数据量:
- 8位寄存器:最大存储256个二进制数,可以存储一个字节的数据。
- 16位寄存器:最大存储65536个二进制数,可以存储两个字节的数据。
- 32位寄存器:最大存储4294967296个二进制数,可以存储四个字节的数据。
- 64位寄存器:最大存储18446744073709551616个二进制数,可以存储八个字节的数据。
在实际应用中,寄存器通常用于存储以下类型的数据:
- 整数:整数是指没有小数点的数字,例如10、20、30等。
- 浮点数:浮点数是指带小数点的数字,例如1.5、2.3、3.14等。
- 字符:字符是指单个的字母、数字或符号,例如A、B、C、1、2、3、$、@等。
- 地址:地址是指内存中某个位置的标识,用于定位数据或指令。
寄存器的位数决定了其所能存储的数据量和类型,在计算机系统中起着重要的作用。
以下是一些具体的例子:
- 通用寄存器:通用寄存器可以存储任意类型的数据,例如整数、浮点数、字符和地址。
- 专用寄存器:专用寄存器只能存储特定类型的数据,例如指令寄存器只能存储要执行的指令,状态寄存器只能存储处理器的状态信息。
寄存器的数量和类型也决定了CPU的性能。一般来说,寄存器越多、位数越高,CPU的性能就越强。
处理器中的寄存器的分类
1)用户可见寄存器:数据寄存器、地址寄存器、条件码寄存器。
2)控制和状态寄存器:程序计数器(PC)、指令寄存器(IR)、程序状态字(PSW)寄存器。
PSW 是一个程序状态字,一般来说是逻辑概念,描述了处理器在执行程序时的状态和控制信息。PSW通常包含以下标志位:
- 进位标志(C):表示算术运算的结果是否产生了进位。
- 溢出标志(V):表示算术运算的结果是否发生了溢出。
- 零标志(Z):表示运算结果是否为零。
- 负标志(N):表示运算结果是否为负数。
- 辅助进位标志(A):用于BCD(二进制编码十进制)运算。
- 中断使能标志(I):控制是否允许中断。
- 方向标志(D):用于控制字符串操作的方向。
术语使用的不同:有些教程可能会将 PSW 描述为一个特殊的寄存器,这可能会让人认为 PSW 是肯定是一个物理寄存器。实际上,PSW 更确切地是一个逻辑概念,它的信息可以存储在特定的寄存器中,但 PSW 本身可以不是一个单独的、独立的物理寄存器。
处理器架构的差异:不同的处理器架构可能会以不同的方式实现 PSW。一些架构可能确实有一个称为 PSW 的特殊寄存器,而另一些可能通过状态寄存器或标志寄存器来实现 PSW 的功能。
总结来说,PSW 是一个程序状态字的逻辑概念,描述了处理器在执行程序时的状态和控制信息。在某些处理器架构中,PSW 的信息可以存储在一个特殊的寄存器中,但 PSW 本身可以不是一个独立的物理寄存器。因此,在不同的上下文和教程中,PSW 可能被描述为一个特殊的寄存器,这种描述方式应当理解为 PSW 的信息存储方式之一,而非 PSW 本身必须是一个寄存器的物理存在。
程序状态字寄存器是一个保存各种状态条件标志的寄存器。
指令执行的过程
指令执行过程可以分为以下几个步骤:
- 取指(Fetch):从内存中取出当前程序计数器(PC)指向的指令,并将其存储到指令寄存器(IR)中。然后,PC指向下一条指令。
- 译码(Decode):将取出的指令进行译码,解析出操作码(Opcode)和操作数(Operands)。
- 执行(Execute):根据译码结果,由ALU执行指令操作,如算术运算、逻辑运算、数据传输等。
- 访存(Memory Access):如果指令需要访问内存(如读取或写入数据),则在此阶段进行内存操作。
- 回写(Write-back):将ALU的运算结果或访存的数据写回到指定的寄存器或内存位置。
第三节 存储系统
涉及操作系统如何管理和使用计算机系统中的存储资源,包括内存(主存)、虚拟内存和文件系统等。
存储系统是指负责管理和存储数据的硬件和软件。
CPU能直接访问的存储类型是:内存。
存储系统的基本概念
- 内存(主存):
- 内存是计算机系统中用于存储程序和数据的物理设备。操作系统通过内存管理来分配和管理内存的使用,包括分配空间给进程、处理内存碎片、虚拟内存管理等。
- 虚拟内存:
- 虚拟内存是操作系统提供的一种技术,通过将部分数据和程序存储在磁盘上,来扩展可用的物理内存空间。这种技术使得每个程序都有自己的虚拟地址空间,从而提高了系统的灵活性和多任务处理能力。
- 文件系统:
- 文件系统是操作系统中用于管理存储设备(如硬盘)上数据和信息的组织方式。文件系统负责文件的存储、检索、管理和保护,使得用户和应用程序能够方便地访问和操作文件。
- 缓存:
- 缓存是存储系统中的一种高速临时存储,用于暂时存放频繁访问的数据,以加快访问速度。操作系统和硬件设备(如CPU和磁盘)都使用缓存来优化性能。
存储系统的管理与优化
- 内存管理:
- 包括内存分配与回收、地址映射、内存保护和共享机制等。操作系统通过内存管理单元(MMU)和硬件支持来实现对物理内存和虚拟内存的管理。
- 虚拟内存管理:
- 实现了物理内存和磁盘空间之间的透明映射,允许程序访问比物理内存更大的地址空间。包括页面置换算法(如LRU、FIFO等)、页面错误处理(缺页中断处理)等。
- 文件系统管理:
- 提供对文件的组织、存储、检索和管理。包括文件的命名、目录结构、存储空间的分配与释放、文件保护和权限控制等功能。
- 缓存管理:
- 确保缓存的有效使用,提高数据访问效率。包括缓存替换算法(如LRU)、缓存一致性和失效处理等。
存储系统的性能和安全性
- 性能优化:
- 通过合理的内存管理策略、高效的页面置换算法、优化文件系统结构和使用快速访问技术(如SSD)等手段,提高存储系统的响应速度和整体性能。
- 数据安全和一致性:
- 实施数据保护措施,如备份、数据恢复、访问控制和加密技术,确保数据的安全性和完整性。
- **存储保护:**必须有硬件支持
- 界地址寄存器(也叫界限寄存器);它在CPU中,存放用户作业在内存中的下限(下界寄存器)和上限(上界寄存器);在CPU访问内存时判断是否越界。
- 存储保护键:在界限寄存器的基础上,每个存储块都有一个与其相关的由二进制位组成的存储保护键,附在每个存储块上;作业进入内存时,OS为作业分配一个唯一的存储保护键号;最终分配给这个作业的每个存储块都将保护键设置为该存储保护键号。OS将作业送入CPU时,键号存入PSW的存储保护键域中供CPU访存时核对。
常见的存储器类型:
读写型(RAM):最常见的就是内存。
只读型(ROM):不能随意地用普通方法向其中写入数据,比如BIOS;ROM的变型有PROM(可编程ROM)和EPROM(可用特殊紫外线擦除数据,然后用EPROM写入器先写入数据)。
1. 主存(Main Memory)
主存是计算机系统中用于存储程序和数据的物理存储器,也称为内存。它的主要特点包括:
- 易失性:主存中的数据在断电时会丢失。
- 高速访问:CPU可以直接访问主存,速度比较快。
- 直接作用于CPU:主存是CPU直接操作的存储区域,用于存放当前运行的程序和数据。
2. 辅助存储器(Auxiliary Storage)
辅助存储器是用来扩展主存储器的存储容量,并且能够长期保存数据的设备,包括:
- 硬盘驱动器(Hard Disk Drive, HDD):用于持久存储数据,速度比主存慢但容量大。
- 固态硬盘(Solid State Drive, SSD):基于闪存存储技术,比传统机械硬盘速度更快。
- 光盘(CD、DVD等):用于存储大量数据,如音频、视频等。
- 磁带:用于大容量数据的备份和长期存储,速度较慢但成本低廉。
3. 虚拟存储器(Virtual Memory)
虚拟存储器是一种操作系统提供的技术,通过将部分程序或数据存储在辅助存储器(通常是硬盘)上,来扩展实际物理内存的容量。其主要功能包括:
- 内存管理扩展:允许每个程序都有自己的虚拟地址空间。
- 页面置换:在内存不足时,操作系统会根据页面置换算法将不常用的页面(页)移出内存,以释放空间给新的页面。
4. 缓存存储器(Cache Memory)
缓存存储器位于CPU和主存之间,作为一种高速缓存,用于存放当前CPU正在访问的数据和指令。其主要特点包括:
- 速度快:缓存存储器的访问速度比主存更快。
- 层次结构:现代计算机系统通常包括多级缓存(如L1、L2、L3缓存),以提高数据访问的效率。
5. 寄存器(Registers)
寄存器是位于CPU内部的最快速的存储器,用于存放当前正在执行的指令、操作数和中间结果。寄存器的主要特点包括:
- 速度极快:寄存器位于CPU内部,访问速度比任何其他存储器都要快。
- 容量有限:寄存器数量有限,每个CPU有一组固定的寄存器。
存储分块
存储的最小单位是:二进制位。
最小的编址单位是:字节。
2个字节 = 1个"字"。
4个字节被称为"双字"。
一般计算机系统将存储器分块,以块为最小单位为划分空间,块有时也被称作"页(Page)"。
常用的块大小有:512B、1KB、4KB、8KB等。
存储器的层次结构
设计目标:容量大、速度快、成本低
存储访问局部性原理:访问局部性分为两种基本形式,一种是时间局部性,另一种是空间局部性。时间局部性指的是,程序在运行时,最近刚刚被引用过的一个内存位置容易再次被引用,比如在调取一个函数的时候,前不久才调取过的本地参数容易再度被调取使用。
空间局部性指的是,最近引用过的内存位置以及其周边的内存位置容易再次被使用。空间局部性比较常见于循环中,比如在一个数列中,如果第3个元素在上一个循环中使用,则本次循环中极有可能会使用第4个元素。(这一点在计算机系统结构这门课程中有说明)
第四节 中断机制
中断机制是一个非常重要的主题。中断是计算机系统中一种异步事件处理机制,用于响应由外部设备或内部事件引起的突发事件。
中断机制必须靠相关的硬件支持。是现代计算机系统的核心机制之一。
中断的定义和作用
中断是一种由硬件或软件发起的信号,用于打断CPU正常执行的程序流程,转而处理特定的事件或条件的过程。
中断是CPU对系统中或系统外发生的异步事件(不定时的随机的事件)的响应。
中断系统可以使CPU暂时停止正在执行的任务,去处理更紧急的中断请求,然后再返回到原来的任务中断点继续执行。
其主要作用包括:
- 响应外部事件:如设备IO完成、时钟周期、硬件错误等。
- 处理异常情况:如除零错误、内存访问冲突等。
- 系统调用:用户程序请求操作系统提供的服务和资源。
中断的分类
一般可以分为:
强迫性:随机性强
- 程序性中断
- 时钟中断
- I/O中断
- 控制台中断(退出、终止...)
- 硬件故障
自愿性:通常由访管指令引起
按照中断源划分:
- 硬件中断:
- 由外部硬件设备引发的中断,如IO完成、时钟中断等。
- 硬件中断通常通过中断控制器(如PIC、APIC等)进行管理和分发。
- 软件中断:
- 也称为异常,由CPU执行指令期间检测到的错误或特殊条件引发,如除零错误、页错误等。
- 软件中断还包括系统调用,用户程序请求操作系统提供的服务。
几种典型的中断
(1) I/O中断
- 正常
- 异常
(2)时钟中断
计算机系统多道能力实现的重要条件之一。
(3)硬件故障中断
(4)程序性中断
指令出错、越权、越界。
(5)系统服务请求(自愿性)
中断处理过程
- 中断请求与接收(Interrupt Request):
- 硬件设备或软件触发中断,向CPU发送中断请求信号。
- 中断响应(Interrupt Response):
- CPU在每条指令执行周期内的最后时刻扫描中断寄存器;发现存在中断则转去处理,否则继续执行下一条指令。
- CPU在接收到中断请求后,暂停当前执行的程序,保存当前执行状态(程序计数器、寄存器状态等),转入内核态并跳转(根据中断向量代号查询中断向量表)到相应的中断处理程序(中断服务例程)。
- 中断向量查找:
- CPU根据中断向量表查找相应的ISR地址。
- 执行中断服务例程(Interrupt Service Routine, ISR):
- 中断服务例程是一段特殊的代码,用于处理特定类型的中断事件。
- ISR负责完成中断事件的处理,可能包括与硬件设备通信、数据处理、状态更新等操作。
- 中断处理完毕(Interrupt Completion):
- ISR执行完成后,CPU恢复之前的执行状态。
- 继续执行被中断的程序或者根据调度算法选择下一个执行程序。
中断处理的关键问题
- 中断嵌套和优先级:
- 多个中断事件同时发生时,需要管理其优先级,确保重要事件优先处理。
- 固定优先级:按设备或者按设备离CPU的远近。
- 轮转法:公平
- 中断可能存在嵌套,即在处理一个中断时发生了另一个中断请求。
- 策略1:处理中断时,禁止其它中断。
- 策略2:中断嵌套;允许高优先级的中断打断低优先级的中断。
- 中断屏蔽:
- 某些情况下,需要临时禁止或屏蔽某些中断,以防止干扰关键任务的执行。
- PSW中中断屏蔽位;
- 被屏蔽的中断信号,通常仍然保留在中断寄存器中,有些可以以后继续响应,有些被简单地直接丢弃。
- 中断向量和中断向量表:
- 中断向量是一个地址,指向特定中断类型的ISR。
- 中断向量表是一个存储所有中断类型和其对应ISR地址的数据结构。
- 上下文切换:
- 中断处理涉及保存和恢复CPU的执行状态,确保中断处理完毕后能够正确恢复到被中断的程序。
操作系统中的中断管理
操作系统负责管理中断的注册、分发和响应,确保系统能够有效地处理各种硬件事件和异常情况。中断机制是操作系统实现多任务处理、资源管理和用户程序交互的重要基础之一。
第五节 I/O技术
I/O(输入/输出)是计算机与外部设备之间通信的基础。它在数据传输中扮演着关键角色,允许用户与系统交互,应用程序可以访问和处理来自各种来源的数据。
I/O结构
每台外部设备都配有各自的"设别控制器",用于控制在自己设备的运行。
设备控制器与CPU之间的硬件结构就是"I/O结构";他们有不同的设计方案:
1.早期
2.通道
通道独立于处理器;是专门负责数据I/O传输工作的处理单元。
优点是:使CPU与各种外设并行工作;外设与CPU都能访问内存。
对I/O处理要求高的系统才有通道,低档机中没有通道。
3.直接存储访问技术DMA
通过系统总线中的一个独立控制单元(DMA控制器)自动地控制成块数据在内存和I/O单元之间的传递。
例如:当CPU需要读写一整块数据的时候,他给DMA控制器发一条指令,包括处理这段数据的全部信息;然后CPU就可以处理其他事情了。DMA控制器会去处理数据的传输。当处理完成后给CPU发生中断信号。
DMA大大提高了处理I/O的效能。
I/O 系统的关键组件
- I/O 设备: 这些是物理硬件组件,使计算机能够与外部环境进行交互。例如键盘、鼠标、显示器、打印机、硬盘驱动器和网络接口卡等。
- 设备驱动程序: 这些是软件程序,充当操作系统和 I/O 设备之间的媒介。它们将操作系统的请求转换为特定设备可以理解和处理的命令。
- I/O 子系统: 这些是操作系统内部的软件模块,用于管理和协调 I/O 操作。它们处理设备分配、数据缓冲和错误处理等任务。
- I/O 管理软件: 该软件负责 I/O 系统的整体管理,包括设备配置、调度 I/O 请求和确保数据完整性等任务。
I/O 技术的主要分类
- 程序控制I/O:
- 轮询(Polling):CPU主动检查I/O设备的状态,直到设备准备好进行数据传输。这种方式会浪费CPU时间,效率较低。
- 在轮询机制中,CPU定期检查I/O设备的状态寄存器,判断设备是否准备好进行数据传输。
优点:实现简单,不需要额外的硬件支持。
缺点:效率低下,因为CPU需要不断轮询,浪费处理能力。
- 中断驱动I/O:
- I/O设备准备好数据时,通过中断通知CPU进行数据传输。中断驱动I/O减少了CPU的等待时间,提高了系统效率。
- 当I/O设备准备好数据时,向CPU发送中断信号。
CPU响应中断,暂停当前任务,执行中断服务例程(ISR)来处理I/O操作。
优点:提高了CPU利用率,减少了等待时间。
缺点:实现复杂,需要处理中断优先级和中断嵌套。
- 直接内存访问(DMA, Direct Memory Access):
- DMA控制器直接管理I/O设备和内存之间的数据传输,无需CPU干预。DMA方式进一步提高了I/O操作的效率和系统性能。
- DMA控制器在I/O设备和内存之间直接传输数据,CPU只需启动和结束传输过程。
DMA方式有单次传输、块传输、循环传输等模式。
优点:大幅提高了数据传输速度,减轻了CPU负担。
缺点:需要额外的硬件支持(DMA控制器)。
I/O调度
操作系统需要对多个I/O请求进行调度,以提高系统性能和响应时间。常见的I/O调度算法包括:
- 先来先服务(FCFS, First-Come, First-Served):
- 按照请求到达的顺序处理I/O请求。
- 简单但可能导致某些请求等待时间过长。
- 最短寻道时间优先(SSTF, Shortest Seek Time First):
- 优先处理与当前磁头位置最接近的请求。
- 减少了磁盘寻道时间,但可能导致“饥饿”现象。
- 扫描算法(SCAN)和电梯算法(Elevator Algorithm):
- 磁头在磁盘上来回移动,沿途处理所有请求。
- 优点:减少了平均寻道时间,避免了“饥饿”现象。
缓存技术
目的:解决部件之间速率不匹配问题。
第六节 时钟
时钟是操作系统中一个重要的组成部分,它为系统提供时间管理功能,并用于调度进程、同步和计时等操作。时钟通常由硬件实现,并通过软件进行管理和使用。
时钟在操作系统中的作用
系统时间的维持:
通过时钟中断,操作系统可以维持当前的系统时间(如系统启动后的时间)。操作系统使用时钟中断定期更新系统时间变量。
进程调度:
时钟中断用于实现时间片轮转调度,即在多任务操作系统中,定期切换CPU的执行进程。操作系统根据时钟中断来决定何时进行上下文切换,确保各进程公平地获得CPU时间。
定时任务管理:
操作系统使用时钟来管理定时任务(如定时器事件、延时任务等)。通过设定定时器,操作系统可以在特定时间点或经过特定时间间隔后执行某些任务。
性能监控和计时:
时钟用于测量程序执行时间、进程运行时间、系统性能等。通过时钟,操作系统可以收集和记录各种时间统计信息,如CPU利用率、进程响应时间等。
- 在多道程序运行环境中,为系统发现陷入死循环的作业。
- 在分时系统中,时间间隔实现时间片轮转。
- 在实时操作系统中,按要求的时间间隔输出正确的时间信号。
- 定时唤醒外部事件。
- 记录时间与事件。
分类
硬件时钟:电路中的晶体振荡器,每隔固定时间产生固定的脉冲频率。
软件时钟:计算脉冲数。
用途划分
绝对时钟:关机也保持运行。
相对时钟:间隔时钟。
第七节 系统调用
为了从OS中获得服务。
什么是系统调用
系统调用是操作系统提供给应用程序的一组接口,允许应用程序请求操作系统内核的服务。通过系统调用,应用程序可以完成诸如文件操作、进程管理、内存管理和设备控制等任务,这些任务需要直接与硬件交互或涉及系统资源的管理和调度。
只能由汇编语言直接访问。 系统调用是操作系统提供给编程人员的唯一接口。
系统调用本质上不是独立的程序,而是操作系统内核提供的服务接口。它们是内核中实现的一组例程,应用程序通过特定的调用机制(如陷阱指令)访问这些例程。
注意区分:
系统调用接口和编程语言接口在概念和用途上有显著不同。
在面向对象编程语言(如Java、C#)中,接口是一个抽象类型,定义了一组方法,但不提供具体实现。类可以实现这些接口,并提供具体的实现。
在操作系统上下文中,系统调用作为接口是指操作系统提供给应用程序的一组标准化的、预定义的功能,应用程序可以通过这些接口请求操作系统内核的服务。使用“接口”一词强调操作系统提供的一组标准服务,这些服务已经实现且可供应用程序调用。称其为“类”会引起误解,因为类在面向对象编程中表示具有属性和方法的具体实现。
系统调用的数量和种类因操作系统而异。例如:
- Linux:Linux操作系统包含几百个系统调用,具体数量随内核版本变化。
- Windows:Windows操作系统也包含大量系统调用,具体数量同样依赖于操作系统版本和服务包。
系统调用分类
从功能上划分:
1.操作系统自身所需。
2.作为服务提供给用户。
按模块划分:
1.进程控制类
2.文件操作类
3.进程通讯类
4.设备管理类
5.信息维护类
系统调用的工作原理
- 应用程序发起请求:应用程序通过调用库函数(如标准C库中的函数)发起系统调用请求。
- 陷入内核模式:系统调用引发从用户模式到内核模式的转换,通常通过触发软中断(软件中断)或陷阱指令。
- 内核处理请求:操作系统内核接管控制权,根据系统调用号查找对应的内核服务例程,并执行相关操作。
- 返回用户模式:内核完成系统调用请求后,将控制权返回给应用程序,并将结果返回给调用函数。
容易混淆的概念及其区别
- 库函数:
- 定义:库函数是应用程序直接调用的函数,通常位于标准库中(如C标准库)。
- 区别:库函数是用户态的代码,而系统调用是从用户态进入内核态的接口。库函数可以调用多个系统调用来完成复杂任务。
- API(应用编程接口):
- 定义:API是程序调用的接口,可以是库函数、系统调用或其他程序接口。
- 区别:API的范围更广泛,系统调用是API的一部分,专门提供操作系统内核服务的接口。
- 中断:
- 定义:中断是由硬件或软件引发的事件,用于打断CPU的正常执行流程。
- 区别:系统调用可以通过软件中断机制实现,但中断的范围更广,可以是硬件中断(如I/O设备中断)或异常(如除零错误)。
如何查询系统调用的信息?
- Linux:
- man手册:可以通过
man 2 syscall_name
(例如man 2 open
)查看系统调用的详细信息。 - syscalls表:可以查看内核源码中的
syscalls
表,通常位于arch/x86/entry/syscalls/syscall_64.tbl
等文件中。 - syscall列表:可以通过命令
ausyscall --dump
或getconf SYS_*
查看系统调用列表和编号。
- Windows:
- 微软文档:微软提供的MSDN文档中包含Windows API的详细说明,包括系统调用相关内容。
- 工具和软件:例如Process Monitor等工具可以监控系统调用。
系统调用的示例
Linux中的常见系统调用
- 文件操作:
open()
: 打开文件read()
: 读取文件write()
: 写入文件close()
: 关闭文件
- 进程管理:
fork()
: 创建进程exec()
: 执行新程序wait()
: 等待子进程结束exit()
: 退出进程
- 内存管理:
mmap()
: 映射内存munmap()
: 解除内存映射
- 设备管理:
ioctl()
: 设备控制
Windows中的常见系统调用
- 文件操作:
CreateFile()
: 创建或打开文件ReadFile()
: 读取文件WriteFile()
: 写入文件CloseHandle()
: 关闭文件句柄
- 进程管理:
CreateProcess()
: 创建进程WaitForSingleObject()
: 等待进程结束ExitProcess()
: 退出进程
- 内存管理:
VirtualAlloc()
: 分配虚拟内存VirtualFree()
: 释放虚拟内存
- 设备管理:
DeviceIoControl()
: 设备控制
系统调用与普通的函数调用的区别
1. 执行环境
系统调用
- 执行环境:系统调用会导致从用户模式到内核模式的切换。
- 特权级别:系统调用允许程序访问和操作受保护的系统资源,这些资源通常只有操作系统内核可以直接访问。
普通函数调用
- 执行环境:普通函数调用在用户模式下执行。
- 特权级别:普通函数调用无法直接访问受保护的系统资源,只能在用户空间操作。
2. 安全性与稳定性
系统调用
- 安全性:由于涉及系统资源的访问,系统调用需要在内核模式下执行,操作系统内核会进行严格的权限检查。
- 稳定性:系统调用由操作系统内核管理,内核会确保资源的稳定性和一致性。
普通函数调用
- 安全性:普通函数调用在用户空间执行,权限受限,无法直接操作系统资源。
- 稳定性:普通函数调用的稳定性取决于程序自身的逻辑,没有操作系统内核的保护。
3. 性能开销
系统调用
- 性能开销:系统调用涉及用户模式和内核模式之间的切换,这种模式切换相对耗时。
- 处理过程:需要保存当前进程状态,切换到内核态,执行内核代码,处理完成后再切换回用户态。
普通函数调用
- 性能开销:普通函数调用在同一模式下执行,调用开销较低。
- 处理过程:函数调用和返回的开销包括参数传递、栈帧操作等,开销相对较小。
4. 调用方式
系统调用
- 调用方式:通过特定的系统调用接口,通常需要使用特定的指令(如Intel x86上的
int
指令)触发系统调用。 - 库函数封装:在高级编程语言中,系统调用通常通过库函数(如C标准库)封装,使得调用更为方便。
普通函数调用
- 调用方式:通过编程语言提供的函数调用机制直接调用。
- 调用示例:在C语言中,直接调用函数名即可,如
result = my_function(param);
。
5. 代码示例
系统调用示例(Linux中的read
系统调用)
#include <unistd.h>
#include <fcntl.h>
int main() {
int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
return -1;
}
char buffer[128];
ssize_t bytesRead = read(fd, buffer, sizeof(buffer));
close(fd);
return 0;
}
在这个示例中,open
、read
、close
都是系统调用,通过用户态的库函数封装进行调用。
普通函数调用示例(C语言中的普通函数)
#include <stdio.h>
void my_function() {
printf("This is a normal function call.\n");
}
int main() {
my_function();
return 0;
}
在这个示例中,my_function
是一个普通的用户态函数,直接在用户模式下执行。
系统调用可以根据其功能和用途分为以下几类
- 文件系统操作: 这些系统调用提供对文件系统资源的访问,允许应用程序执行与文件相关的操作。例如:
open()
和close()
:打开和关闭文件read()
和write()
:读写文件中的数据seek()
:将文件指针设置到特定位置mkdir()
和rmdir()
:创建和删除目录stat()
:获取文件或目录信息
- 进程管理: 这些系统调用管理进程的创建、执行和终止。例如:
fork()
:创建新进程exec()
: 在当前进程中执行新程序wait()
:等待子进程完成执行signal()
: 向进程发送信号kill()
: 终止进程
- 设备管理: 这些系统调用提供对硬件设备的访问,允许应用程序与之交互。例如:
open()
和close()
:打开和关闭设备read()
和write()
:读写设备中的数据ioctl()
: 控制特定于设备的操作mmap()
: 将设备内存映射到进程地址空间
- 内存管理: 这些系统调用管理进程内存的分配和释放。例如:
malloc()
和free()
: 分配和释放内存块calloc()
: 分配内存并将其初始化为零realloc()
: 调整现有内存块的大小mmap()
: 将文件或其他内存区域映射到进程地址空间
- 网络通信: 这些系统调用为应用程序提供网络通信功能。例如:
socket()
: 创建用于网络通信的套接字connect()
: 连接到远程套接字send()
和recv()
: 通过网络发送和接收数据listen()
: 接受传入连接bind()
: 将套接字绑定到本地地址
- 进程间通信 (IPC): 这些系统调用支持不同进程之间的通信和同步。例如:
pipe()
: 创建用于单向数据传输的管道mkfifo()
:创建FIFO(Linux/Unix)。CreatePipe()
:创建管道(Windows)。msgget()
:获取消息队列标识符(Linux/Unix)。msgsnd()
:发送消息(Linux/Unix)。msgrcv()
:接收消息(Linux/Unix)。信号量
: 协调对共享资源的访问
signal()
:设置信号处理程序(Linux/Unix)。kill()
:发送信号(Linux/Unix)。raise()
:向自身发送信号(Linux/Unix)。
共享内存
: 在进程之间共享内存
shmget()
:获取共享内存标识符(Linux/Unix)。shmat()
:附加共享内存(Linux/Unix)。shmdt()
:分离共享内存(Linux/Unix)。
- 时间管理: 这些系统调用提供与时间相关的服务,例如获取当前时间、设置计时器和延迟进程。例如:
gettimeofday()
: 获取当前时间和日期times()
: 获取进程和系统时间使用情况sleep()
: 延迟当前进程的执行alarm()
: 设置在指定时间后触发的警报
- 安全: 这些系统调用提供安全相关的功能,例如用户认证、访问控制和加密。例如:
getuid()
: 获取当前进程的用户 IDsetuid()
: 更改当前进程的用户 IDaccess()
: 检查文件访问权限open_secure()
: 使用增强的安全措施打开文件
通常情况下,系统调用并不能被其他方法直接替代。系统调用是应用程序与操作系统 (OS) 交互并访问受保护的系统资源或执行只有操作系统才能执行的操作的一种基本机制。它们为应用程序请求操作系统服务提供了一个安全可控的接口,确保了系统的稳定性和完整性。
虽然实现某些功能可能存在替代方法,但它们可能无法提供与系统调用相同的安全级别、特权级别或效率。例如,一些库或用户空间工具可能提供类似的功能,但它们可能仅限于用户模式的权限范围内运行,无法直接访问受保护的系统资源或执行特权操作。
如何查询系统调用信息
- Linux系统:
- man手册:使用
man 2 syscall_name
(如man 2 open
)查看系统调用的详细信息。 - 内核源码:查看Linux内核源码中的
syscalls
表(如arch/x86/entry/syscalls/syscall_64.tbl
)。 - 系统调用列表:使用命令
ausyscall --dump
或getconf SYS_*
查看系统调用列表和编号。
- Windows系统:
- MSDN文档:微软的MSDN文档提供了Windows API的详细说明,包括系统调用相关内容。
- 工具:使用Process Monitor等工具监控系统调用。