「Linux 系统编程」进程相关概念
1 进程与程序
1.1 什么是程序
定义:程序 是一组静态的指令集合,通常以一个文件的形式存储在磁盘上(例如,/usr/bin/chromium
是一个Chrome浏览器的可执行程序文件)。
本质:只是一堆存储在磁盘上的二进制代码和数据,本身并不执行任何操作。
1.2 什么是进程
定义:进程 是一个 正在执行的程序的实例。当一个程序被加载到内存并开始执行时,就变成了一个进程。执行完毕就会被销毁。
本质:进程 是一个活动的实体,拥有自己的生命周期和状态。进程 不仅是程序的代码,还包括当前的活动(如程序计数器的值、寄存器的内容)、以及运行所需的系统资源(如内存、打开的文件等)。
每个进程都 拥有独立的地址空间 和 系统资源,一个进程通常不会直接影响另一个进程(除非通过进程间通信IPC)。
进程的并发:在操作系统的管理下(通过进程调度、上下文切换),多个进程在一段时间内同时处于已开始运行但尚未结束的状态(宏观上看这些进程像是在同时进行),在单个 CPU 上 模拟出多任务同时执行的效果。
1.3 程序与进程的关系
程序 | 进程 | |
---|---|---|
本质 | 静态的 指令集合(文件) | 动态的 执行实例(活动) |
存在状态 | 永久的,存储在磁盘等介质上 | 暂时的,有生命周期(创建、执行、终止) |
组成 | 代码、静态数据 | 程序代码 + 当前状态(计数器、寄存器) + 相关资源(内存、文件、CPU时间片) |
归属关系 | 一对多:一个程序可以对应多个进程 | 多对一:一个进程只能对应一个特定的程序 |
资源分配 | 不占用系统运行资源(CPU、内存) | 是 系统进行资源分配和调度 的基本独立单位 |
2 并发与并行
并发 | 并行 | |
---|---|---|
核心概念 | 处理多个任务的能力 | 同时执行多个任务的能力 |
本质 | 逻辑上 的同时发生(同一时间段内推进) | 物理上 的同时执行(真正同一时刻一起运行) |
硬件要求 | 单核 CPU 即可实现 | 必须有多核 CPU |
图示 | 交替 | 同时 |
并行是并发的 真子集。并发的范围更广,包含了并行。
3 单道程序设计与多道程序设计
单道程序设计 | 多道程序设计 | |
---|---|---|
允许内存中的程序数量 | 一个 | 多个 |
CPU 利用率 | 极低(大量时间在等待I/O) | 高(CPU总在工作,减少空闲) |
资源使用 | 程序独占全部资源 | 资源由多个程序共享 |
目标 | 简化设计,方便操作 | 最大化系统效率 和吞吐量 |
复杂性 | 管理简单 | 管理复杂,需要解决内存管理、调度、同步等问题 |
时代背景 | 早期批处理系统 | 现代操作系统的 基石 |
多道程序设计是现代所有操作系统(包括Windows, Linux, macOS等)的基础和核心特征。 通过组织多个程序交替共享CPU,解决了单道程序中 CPU等待 I/O 的巨大效率问题。
4 操作系统的存储介质
4.1 高速临时存储介质(内存 / 缓存,断电数据丢失)
高速临时存储介质 的核心特点是读写 速度极快,但 容量较小、成本高,主要用于 OS 临时存放正在运行的程序、数据和内核指令,确保 CPU 能快速获取数据,避免等待低速外存。
4.1.1 SRAM(静态随机存取存储器,构成 Cache)
SRAM(静态随机存取存储器)是构成 CPU缓存(Cache) 的核心硬件基础。SRAM 无需刷新电路,功耗低,具有极低的随机访问延迟,容量通常较小(通常为 MB 级)。
SRAM 作为 CPU 高速缓存(L1/L2/L3 Cache),存放 CPU 最常访问的指令和数据,减少 CPU 与内存的交互延迟。
现代 CPU 的缓存(Cache)分为三级,每一级均使用 SRAM:
-
L1 Cache:每个CPU核心独占,容量32~64KB,分为指令缓存(I-Cache)和数据缓存(D-Cache)。其延迟最低,主要优化速度。通常采用采用高频低延迟的 8T-SRAM。
-
L2 Cache:每个核心独占或共享,容量256KB~1MB,平衡速度与容量。使用高密度 6T-SRAM,容量更大。
-
L3 Cache:多核共享,容量2~64MB,主要减少多核访问主存的冲突。采用低功耗 SRAM。
4.1.2 DRAM(动态随机存取存储器,构成主内存)
与 SRAM 相比,DRAM 的结构更简单,具有更高的密度和更低的成本,但其访问速度较慢,耗电量较大,容量中等(通常为 GB 级)。
DRAM 广泛应用于计算机的 主内存(内存条),存放 OS 内核、正在运行的应用程序(如浏览器、文档)和 临时数据。
4.1.3 SRAM 和 DRAM 总结
SRAM(静态随机访问存储器)和 DRAM(动态随机访问存储器)是两种常用的内存技术。
- 存储方式:SRAM 使用触发器存储数据,不需要定期刷新;DRAM 需要定期刷新以保持数据。
- 速度:SRAM 的读写速度最快,适合用作 CPU 缓存;DRAM 速度较快(慢于 SRAM),但适合较大容量内存。
当 CPU 请求数据时,首先查询 L1 Cache,若未命中则依次查询 L2 和 L3 Cache,最终访问主存(DRAM)。
4.1.4 栈空间和堆空间
栈空间 是操作系统为每个线程分配的一块连续的内存区域,用于管理函数调用和局部变量。它的管理方式非常高效,遵循后进先出的原则。
堆空间 是操作系统提供给应用程序的一块不连续的、全局的、巨大的内存池。它的大小通常只受限于机器的物理内存和虚拟内存大小。
特性 | 栈空间 | 堆空间 |
---|---|---|
管理方式 | 由编译器/操作系统自动管理 | 手动申请释放(C/C++)或由GC管理(Java/C#等) |
分配速度 | 非常快(移动指针) | 相对较慢(寻找空闲块) |
生命周期 | 函数调用期间,随函数返回自动释放 | 动态的,从 malloc/new 开始,到 free/delete 或GC回收结束 |
大小限制 | 较小(通常MB级别) | 很大(仅受限于系统虚拟内存) |
存储内容 | 局部变量、函数参数、返回地址等 | 动态分配的对象和大数据结构 |
内存结构 | 连续的内存块 | 不连续的链表式结构,可能产生碎片 |
主要错误 | 栈溢出(Stack Overflow) | 内存泄漏(Memory Leak)、use-after-free |
4.2 低速持久存储介质(外存,断电数据保留)
这类介质的核心特点是 容量大、成本低,但 读写速度慢(毫秒级或秒级),主要用于 OS 持久化存储用户数据(如文件、照片)、系统文件(如 Windows 的C:\Windows、Linux 的/boot)和 应用程序安装包。
4.2.1 机械硬盘(HDD,Hard Disk Drive)
物理结构:由旋转的磁盘片(磁性材料)、读写磁头组成,通过磁头移动和磁盘旋转实现数据读写。
核心特性:
- 相比 SSD 速度较慢(寻道时间~5-10ms,连续读写速度~100-200MB/s);
- 容量大(TB 级,主流 2-16TB)、成本低(每 GB 成本远低于 SSD);
- 怕震动(磁头易划伤磁盘片导致数据损坏)。
机械硬盘(HDD,Hard Disk Drive)是 传统 PC / 服务器的主要外存,用于存放大量不常快速访问的数据(如备份文件、视频库),或作为早期设备的低成本系统盘。
4.2.2 固态硬盘(SSD,Solid State Drive)
物理结构:使用闪存芯片来存储数据,无机械部件,靠电子信号读写数据。
核心特性:
- 速度快(随机读写速度~1000-7000MB/s,远超 HDD),无寻道时间;
- 抗震性强、噪音低、功耗低;
- 成本高于 HDD,容量逐步提升(主流 512GB-4TB),存在 “写入寿命”(TBW,总写入字节数,消费级 SSD 通常足够日常使用)。
固态硬盘(SSD,Solid State Drive)是 当前主流系统盘(存放 OS 内核、常用应用),大幅提升开机速度、应用启动速度。
可以在自己电脑的任务管理器上看到电脑磁盘的类型:
4.2.3 移动存储介质
这类介质 便携性强,通常即插即用 主要用于跨设备数据传输,OS 需通过驱动支持其读写。
-
U 盘(USB 闪存盘):基于闪存芯片,容量通常 16GB-2TB,接口以 USB 3.0/3.1 为主(速度~100-500MB/s),适合小文件传输(如文档、安装包)。
-
移动硬盘(分 “移动 HDD” 和 “移动 SSD”):
- 移动 HDD:容量 2-16TB,速度~100-200MB/s,适合大容量备份(如照片库);
- 移动 SSD:容量 512GB-4TB,速度~500-2000MB/s,适合高速传输(如 4K 视频)。
4.3 长期归档存储介质(海量数据备份,读写频率低)
这类介质的核心特点是 寿命长、稳定性高,但 读写速度极慢,主要用于 OS 或用户的 “冷备份”(长期不访问但需保留的数据)。
-
光盘(CD/DVD/Blu-ray):速度慢(MB 级 /s),易刮伤,需光驱读取。早期用于存放系统安装镜像(如 Windows 安装光盘)、软件安装包、影音文件,当前逐步被 U 盘 / 网盘替代。
-
磁带(磁带库): 速度慢(顺序读写~100-300MB/s),成本极低。适用于OS 日志、用户海量数据(如银行交易记录、云存储冷数据)的长期归档备份,不适合随机访问。
操作系统存储结构层次示意图:
5 CPU 及其组成
5.1 CPU 中央处理器
CPU 中央处理器 负责执行程序中的指令、进行算术和逻辑运算、控制其他组件协调工作。
核心组成部分:
-
控制单元(CU):负责从内存中 读取指令、解码指令。根据指令的译码结果,生成相应的控制信号,控制运算器、寄存器和其他部件协同工作。
-
算术逻辑单元(ALU):负责执行所有数学运算(加、减、乘、除)和逻辑运算(与、或、非、比较)。
-
寄存器组:是 CPU 内部的微小、高速的存储单元。
寄存器 是 CPU 直接进行操作的地方。寄存器 用于存储当前正在被执行的指令、操作数、中间结果以及指令的地址等。数量很少,但速度极快。
-
缓存(Cache):集成在 CPU 内部的高速存储器。
-
总线接口:负责管理 CPU 与系统其他部分(如内存、输入/输出设备)之间的数据通信。
5.2 CPU 工作举例
以一个简单的加法指令 C = A + B 为例,CPU 的工作流程如下:
-
取指令:控制单元(CU)从内存中 取出 ADD A, B, C 这条指令,并将其 加载到指令寄存器 中。
-
解码指令:控制单元(CU)解码这条指令,明白需要做加法。
-
取数据:CU 指挥总线接口单元,将内存中变量 A 和 B 的值(如果缓存 cache 中有副本,则直接从缓存 cache 中读取)加载到通用寄存器 中。
-
执行计算:CU 命令 算术逻辑单元(ALU)从寄存器中取出 A 和 B 的值进行 加法运算。
-
存结果:ALU 将计算结果 写回另一个寄存器。
-
写回内存:CU 最终将寄存器中的结果 写回内存中变量 C 所在的位置(也会同时更新缓存)。
整个过程将在纳秒级别内完成。
6 MMU 内存管理单元
6.1 MMU 内存管理单元
MMU 内存管理单元(Memory Management Unit)负责处理 CPU 核心发出的内存访问请求,位于 CPU 内。
MMU 内存管理单元 主要功能是 将虚拟地址转换为物理地址。MMU 为每个进程提供一个 独立的、统一的、连续的虚拟地址空间,并将这个虚拟空间 映射到分散的物理内存页上。
为什么需要 MMU:
- 安全性差:如果一个程序可以随意读写其他程序甚至操作系统的内存数据,可能导致系统崩溃或数据泄露;
- 内存管理困难:随着程序的加载和退出,可用物理内存会变得零散破碎,难以分配大块的连续内存;
- 并发困难:每个程序都需要知道自己被加载到物理内存的什么位置,这给同时运行多个程序带来了巨大复杂度。
这就是为什么需要 MMU 内存管理单元,MMU 通过虚拟内存技术解决了上述所有问题。
6.2 MMU 与权限设置
MMU 的工作原理是通过查询页表来实现虚拟地址到物理地址的转换。每个页表项不仅包含物理页帧号,还包含控制该页访问权限的位。
-
P (Present)位:该页是否在物理内存中。如果为
0
,访问会触发缺页异常。 -
R/W (Read/Write)位:
0
= 只读1
= 可读可写- 当CPU处于低特权级(如用户模式)时,尝试写入一个
R/W=0
的页会触发保护异常。
-
U/S (User/Supervisor)位:
0
= Supervisor 页。只有 操作系统内核 可以访问。1
= User 页。所有程序(用户态和内核态)都可以访问。- 当CPU处于低特权级(用户模式)时,尝试访问一个
U/S=0
的页会触发保护异常。
-
XD (Execute Disable) 位(Intel)或 NX (No Execute) 位(ARM):
1
= 该页的内容 不可作为指令执行。- 这是一种重要的安全特性,防止攻击者将恶意代码写入数据区(如栈或堆)然后跳转执行。
MMU 在每次内存访问时,检查当前 CPU的特权级和访问类型(读、写、执行),并与页表项中的这些权限位进行比对。如果违反任何一条规则,MMU会立即向 CPU 报告一个 异常。
7 PCB 进程控制块
7.1 PCB 进程控制块及其组成
PCB 进程控制块(Process Control Block)是操作系统用于 管理和描述一个运行中程序(进程)的数据结构。存放在操作系统内核所在的内存空间(内核空间)中。
PCB 进程控制块 包含了进程中的重要信息(如进程 id、进程状态、工作位置等),从而支持操作系统对进程进行有效的管理和调度。
PCB 进程控制块 主要涵盖信息:
- 进程标识:包括进程 ID(PID)、父进程 ID(PPID)等。
- 进程状态:如运行、就绪、阻塞等。
- CPU 寄存器状态:保存进程在切换时的 CPU 上下文。
- 调度信息:包含优先级、调度队列位置等。
- 内存管理信息:记录进程所使用的地址空间,包括代码段、数据段和堆栈段。
- 资源分配信息:跟踪进程所持有的文件描述符、打开的设备等资源。
- 会计信息:记录 CPU 使用时间、内存使用量等统计信息。
7.2 PCB 进程控制块工作(以进程切换为例)
-
中断发生:一个正在运行的进程由于时间片用完或等待 I/O 等原因需要被挂起。
-
保存现场:操作系统将当前 CPU 中所有寄存器的值保存到该进程的 PCB 中。
-
选择新进程:调度器根据各个进程 PCB 中的调度信息(如状态、优先级),选择一个就绪的进程来运行。
-
恢复现场:操作系统将新进程 PCB 中保存的寄存器值(上次的现场)全部重新加载到 CPU 的各个寄存器中。
-
开始运行:程序计数器等寄存器被恢复,CPU 开始执行新进程的代码。
这个过程被称为 上下文切换,而 PCB 就是上下文切换的核心。
7.3 Linux 中的 PCB
在 Linux 系统中,PCB 的具体实现是一个名为 task_struct
的非常庞大的结构体(定义在 sched.h
头文件中)。它包含了上述的所有信息以及其他更多信息。
在 Linux 系统中,可以通过命令 ps -aux
查看到的进程信息,绝大部分都来自于每个进程对应的 task_struct
:
7.4 进程的 5 种状态
-
新建
进程正在被创建(例如,通过
fork()
系统调用)。操作系统正在为其 分配PCB、初始化资源、建立地址空间 等。这是一个短暂的准备状态。 -
就绪
进程 已准备好运行,只差CPU。它已经获得了除CPU之外所有必需的资源(如内存、文件等)。通常有多个进程处于就绪状态,它们在一个叫 就绪队列 的数据结构中排队,等待操作系统的调度器来选择。
-
运行
进程 正在CPU上执行其指令。在单核CPU系统中,任何时刻最多只有一个进程处于运行状态。
-
阻塞
进程 正在等待某个事件的发生,在事件发生之前无法继续执行(例如,等待用户输入、等待磁盘读取数据、等待另一个进程发来信号)。处于阻塞状态的进程即使分配CPU给它,它也无法运行。它们会在 阻塞队列 中等待。
-
终止
进程 已经结束执行(正常结束或被强制杀死)。操作系统开始回收分配给它的资源(内存、打开的文件等),并销毁其PCB。是一个清理和销毁的状态。