欢迎光临
我们一直在努力

进程属性深入了解(上篇):核心标识、状态与内存属性

进程是操作系统进行资源分配和独立调度的基本单位,其所有运行状态、资源信息都被内核记录在专属的数据结构中。上篇我们从标识身份、生命周期状态、内存空间三个核心维度,结合图示拆解进程的基础属性。

一、进程的 “身份档案”:标识类属性

操作系统通过一组唯一的标识来管理每一个进程,这些标识全部存储在 ** 进程控制块(PCB,Process Control Block)** 中。PCB 是进程存在的唯一标志,相当于进程的 “档案袋”。

1. 进程控制块(PCB):所有属性的载体

PCB 是操作系统内核维护的结构体,每创建一个进程就会生成对应的 PCB,进程销毁时 PCB 也会被回收。它集中保存了进程运行所需的全部信息,大到内存权限,小到寄存器快照,都在 PCB 中有对应字段。

经典的 PCB 结构分为三大类信息:进程标识、处理器状态、进程控制信息,具体字段如下:

<div align="center"> <img src="…" ref="ref_4_0" alt="经典PCB结构示意图"> <p>图1:经典PCB结构字段示意图</p> </div>

以 Linux 系统为例,PCB 的具体实现是task_struct结构体,里面包含了上百个字段,完整描述了一个进程的所有属性。

2. 核心标识属性:PID、PPID、UID/GID

最基础的进程标识有四个,对应进程的 “身份信息”:

  • PID(进程 ID):系统全局唯一的非负整数,是进程最核心的标识。比如 Linux 中 PID=1 的进程是systemd,是所有用户进程的 “始祖”。
  • PPID(父进程 ID):创建当前进程的进程的 PID。进程不能凭空产生,都是由父进程通过fork创建,因此每个进程都有父进程,形成树形的进程关系。
  • UID/GID(用户 ID / 组 ID):标识进程属于哪个用户、哪个用户组,决定了进程的文件访问权限。普通用户创建的进程默认继承当前用户的 UID。

举例理解: 在 Linux 终端执行ps -l,可以看到当前 shell 进程的 PID、PPID、UID 等信息:

plaintext

F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 1000 2345 2301 0 80 0 – 5623 wait pts/0 00:00:00 bash

这里 UID=1000 是当前普通用户,PID=2345 是 bash 进程自身,PPID=2301 是启动它的终端进程。

二、进程的 “生命周期”:状态属性

进程从创建到销毁的整个生命周期中,会因为资源等待、调度切换等原因,在不同状态之间动态切换。状态属性描述了进程当前 “正在做什么”、“能不能运行”。

1. 经典五态模型

操作系统理论中最基础的是三态模型(就绪、运行、阻塞),扩展后形成五态模型,完整覆盖进程的全生命周期:

<div align="center"> <img src="…" ref="ref_8_0" alt="进程五态转换图"> <p>图2:进程五态模型与转换逻辑</p> </div>

五个状态的含义:

  • 新建态:进程正在被创建,PCB 已生成但资源未分配完成,还没进入就绪队列。
  • 就绪态:进程已经具备所有运行条件,只等 CPU 调度。系统中所有就绪进程会排成 “就绪队列”。
  • 运行态:进程正在 CPU 上执行指令。单核 CPU 同一时刻只有一个进程处于运行态。
  • 阻塞态(等待态):进程因为等待某个事件(比如读磁盘、等网络数据)而暂停运行,即使 CPU 空闲也无法执行。
  • 终止态:进程运行结束或异常退出,等待系统回收资源。
  • 2. Linux 系统的实际进程状态

    在 Linux 中,进程状态在五态基础上做了更细的划分,用单个字母标识:

    • R(Running/Runnable):运行或就绪态,对应理论中的运行 + 就绪,都在 CPU 的运行队列里。
    • S(Sleeping):可中断睡眠,对应阻塞态,等待事件时可以被信号唤醒。比如执行sleep 10的进程就是 S 态。
    • D(Disk Sleep):不可中断睡眠,一般是在等待硬件 IO 完成,不能被信号打断。比如进程正在读写磁盘时可能进入 D 态。
    • T(Stopped):停止态,进程被暂停(比如调试时按下 Ctrl+Z),收到恢复信号才会继续运行。
    • Z(Zombie):僵尸态,进程已经结束,但父进程还没调用wait回收它的 PCB 资源。

    举例理解: 执行ps aux | grep sleep,可以看到睡眠中的进程状态为 S:

    plaintext

    user 3456 0.0 0.0 4356 720 pts/0 S+ 10:00 0:00 sleep 100

    三、进程的 “内存地盘”:虚拟地址空间属性

    每个进程都拥有独立的虚拟地址空间,这是操作系统给进程的 “专属内存视野”。进程以为自己独占整个内存,实际上内核通过页表把虚拟地址映射到真实的物理内存。

    1. 虚拟内存的分段布局

    一个典型进程的虚拟地址空间从低地址到高地址,被划分为多个功能明确的段:

    <div align="center"> <img src="…" ref="ref_17_0" alt="进程虚拟内存布局图"> <p>图3:Linux进程虚拟地址空间分段布局</p> </div>

    各段的作用:

  • 代码段(Text 段):存储程序的机器指令,只读不可修改,防止程序被意外篡改。
  • 数据段(Data 段):存储已初始化的全局变量、静态变量,可读可写。
  • BSS 段:存储未初始化的全局变量、静态变量,程序启动时会被自动初始化为 0。
  • 堆(Heap):动态内存区域,由程序员手动申请和释放(比如 C 语言的malloc/free),地址从低向高增长。
  • 栈(Stack):存储函数调用的局部变量、参数、返回地址,由系统自动分配回收,地址从高向低增长。
  • 内核空间:高地址的一部分是内核专属区域,所有进程共享,用于执行系统调用、内核代码。
  • 2. 直观举例:变量存在哪里?

    看一段简单的 C 代码,不同的变量对应不同的内存段:

    c

    运行

    int a = 10; // 已初始化全局变量 → Data段
    int b; // 未初始化全局变量 → BSS段
    void main() {
    int c = 20; // 局部变量 → 栈
    int *p = malloc(100); // malloc申请的内存 → 堆
    static int d = 30; // 静态局部变量 → Data段
    }

    通过/proc/[PID]/maps文件,可以直接查看一个进程真实的内存分段地址,验证上述布局。


    下篇我们将继续讲解进程的调度属性、IO 资源属性、权限与家族属性,进一步深入理解进程的运行机制。


    谢谢

    赞(0)
    未经允许不得转载:171主机测评 » 进程属性深入了解(上篇):核心标识、状态与内存属性
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址