mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
2047 字
7 分钟
Linux 服务器高阶编程(5):进程基础与地址空间

Linux 服务器高阶编程(5):进程基础与地址空间#

一、什么是进程:与程序有何区别#

操作系统进行执行与调度的基本单位。

启动一个程序时,系统为这次运行建立相应的进程,使程序里的任务能够被调度执行。

对比程序进程
状态存放在磁盘上的静态代码和数据程序的一次动态运行实例
是否正在执行不一定正处于运行生命周期中,可能在运行、等待或暂停
占用资源至少占磁盘空间运行时涉及地址空间、CPU 调度及其他系统资源
关系同一个程序可被多次启动每次启动可产生不同的进程实例

二、单进程、多进程与 CPU 时间片#

1. 单进程与多进程#

单进程按顺序处理任务,遇到等待时,后续工作也可能跟着等待。多进程让不同进程分别承担工作:一个进程等待时,CPU 可以去执行另一个进程的任务。不过多进程并非必然更快,因为创建进程、切换、通信和内存占用都有成本。

2. 分时复用、并发与并行#

在单核上,多个就绪进程可以轮流获得 CPU 的一段使用时间

  • 并发:一段时间内多个任务都在推进;在单核上通常表现为交替执行
  • 并行:多个任务在同一时刻分别占用不同执行单元,真正同时运行;多核 CPU 可以提供这种条件
  • 切换开销:切换进程不是零成本;进程过多时,调度成本可能抵消收益

三、进程的地址空间与 PCB#

32 位 Linux 进程:低地址一侧约 0—3 GiB 为用户空间,高地址一侧约 3—4 GiB 为内核空间

区域职责
用户空间存放进程执行任务用的代码、数据、堆、栈、映射等
内核空间由内核管理进程、调度、内存等系统信息,普通用户程序不能直接任意读写

PCB:进程控制块#

PCB记录进程的管理信息

PID:进程标识#

PID 是进程 ID。在同一 PID 命名空间里,同时存在的进程不会共用同一 PID;进程退出并被回收后,PID 将来可以再次分配。因此 PID 是运行期间的标识,不是永久身份证号。

四、用户空间里放什么#

区域说明
命令行参数、环境变量程序启动时由外部传入的信息;可通过 main 参数等使用
栈函数调用、局部变量、临时数据等
映射区动态库、文件映射等
堆程序运行时动态申请与释放的数据
数据段已初始化的全局变量、静态变量
BSS 段未显式初始化或初始化为零的全局变量、静态变量
代码段程序机器指令,即要执行的代码

内核保存“怎样识别、管理这个进程”的信息;用户空间主要容纳进程要执行的代码及其工作数据。动态库通常可以映射到进程地址空间;静态库则一般在链接时并入可执行文件,不能简单说两种库都以同样方式单独映射。

五、物理内存、虚拟内存、页与交换#

1. 为什么引入虚拟地址#

磁盘与内存:磁盘适合持久保存数据,内存访问通常快得多,但断电后普通 RAM 中的数据不能继续保留。

随后引出进程使用的虚拟地址与机器上的物理内存:程序通常操作自己的虚拟地址,系统通过页表等机制将它映射到物理页。不同进程可使用相同的虚拟地址数值,却映射到不同物理页。

可以把它理解为两层:

进程看到的虚拟地址 → 页表映射 → 物理内存中的页框

这样既便于隔离不同进程,也使内核能够更灵活地安排物理内存。虚拟地址空间的大小不等于实际已分配、已驻留的物理内存大小。

2. 页与地址范围#

页表级数、页大小会随架构和配置变化

3. 交换(swap)#

内存中暂时不活跃的数据可转移到磁盘,需要时再取回,它可以缓解物理内存压力,但磁盘访问慢,频繁换入换出会影响性能。并非每份进程数据都会被交换;是否能够交换、何时交换由具体系统策略决定。

4. 进程隔离与共享#

不同进程默认有各自的用户态虚拟地址空间,不能拿一个进程里的普通指针直接访问另一个进程的私有变量

“进程隔离”不等于物理页永远不能共享。

共享库、共享内存以及写时复制等机制,都可能让多个进程在受控条件下映射同一物理页;写权限、同步与隔离规则由系统保证。

六、内存访问权限#

Linux 中在 mmap 等接口上常见的标志如下:

标志含义
PROT_READ允许读
PROT_WRITE允许写
PROT_EXEC允许执行
PROT_NONE不允许访问

需要同时读写时,可以按位或组合:PROT_READ | PROT_WRITE

七、进程状态及转换#

状态解释典型原因
就绪已具备运行条件,正在等待 CPU新任务准备完毕,或时间片用完后再排队
运行获得 CPU,正在执行指令调度器选中
阻塞/睡眠等待事件、I/O 或定时到期,暂不能继续执行sleep()
挂起暂时不参与正常运行,需要恢复后再进入就绪内存内容换出到外存
终止执行完毕、异常退出或被结束生命周期结束

主要转换关系

新生 → 就绪 ⇄ 运行 → 终止
↑ │
├── 阻塞/睡眠(事件到来或定时结束后回就绪)
└── 挂起(恢复后回就绪)

具体说:就绪获得 CPU 后进入运行;运行用完时间片可回到就绪;运行时等待某事可进入阻塞;等待条件满足后先回就绪,而不是直接占用 CPU;进程终止后不能再继续执行。

Linux 的僵尸进程与孤儿进程:

  • 僵尸:子进程已经退出,但父进程尚未通过 wait 等方式回收其退出信息,仍保留少量进程记录;不是每个退出的进程都会长期变成僵尸。
  • 孤儿:父进程先退出、子进程还活着;子进程会被 init 或其他负责收养的进程接管。“孤儿”描述亲子关系,不是与运行/睡眠并列的调度状态。

八、为何切换进程要保存和恢复现场#

若单核 CPU 让进程 A、B 交替执行,寄存器属于 CPU,并不是每个进程各有一套物理寄存器。

A 做 count 加一时,可能先把旧值读入寄存器、执行加法,再写回;如果此时切换给 B,B 改写了同一个寄存器,而 A 恢复时继续把 B 的值当成自己的中间结果,计算就会出错。

因此,调度切换需要保存 A 的执行现场,包括必要的寄存器状态及继续执行所需的控制信息;运行 B;等 A 再次获调度时,恢复 A 的现场,它才能从中断的位置继续。

A 正在运行 → 保存 A 的上下文 → B 运行
↓
A 再获 CPU ← 恢复 A 的上下文 ← B 让出 CPU

分时复用 + 上下文保存/恢复,共同使多个进程能够可靠地交替使用一个 CPU。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Linux 服务器高阶编程(5):进程基础与地址空间
https://joyanblog.com/posts/linux-server-advanced-programming-05-process-basics-address-space/
作者
Joyan
发布于
2026-10-11
许可协议
CC BY-NC-SA 4.0

目录