C高级:Linux进程基础学习记录

Linux 进程管理详解

在操作系统中,进程(Process)是程序的一次动态执行过程,也是系统进行资源分配和调度的基本单位。与静态的程序代码不同,进程包含了程序代码、当前活动(如程序计数器的值)、处理器寄存器的状态、堆栈数据以及分配给它的系统资源(如打开的文件、内存空间等)。简而言之,进程是一个“正在运行中的程序实例”。以下是我在职坐标的学习记录:

1. 查看所有进程详细信息的指令

在 Linux 系统中,最常用的查看进程信息的命令是 ps。要获取系统中所有进程的详细信息,通常使用以下两种格式:

  • ps aux:这是 BSD 风格的命令,常用于查看系统中所有用户的进程,并显示详细的资源占用情况。
  • ps -ef:这是 System V 风格的命令,同样用于列出所有进程,并展示完整的父子进程关系。

2. 常见头部字段解释

执行上述 ps 命令后,输出结果通常包含多个列,以下是几个核心字段的含义:

  • USER:启动该进程的用户账户名称。
  • PID:进程 ID(Process ID),是操作系统为每个进程分配的唯一标识符。
  • PPID:父进程 ID(Parent Process ID),即创建该进程的父进程的 PID。
  • %CPU / %MEM:分别表示该进程占用的 CPU 时间百分比和物理内存百分比。
  • STAT:进程当前的状态(如 R 表示运行,S 表示休眠,Z 表示僵尸进程等)。
  • VSZ:虚拟内存占用大小
  • RSS:物理内存占用大小
  • TTY:终端编号
  • START:开始时间
  • END:结束时间
  • COMMAND:启动该进程的命令名称及其参数。

3. 任务控制与进程切换

jobs 命令的功能

jobs 命令用于列出当前 Shell 会话中正在后台运行或已暂停的任务及其状态。它仅对当前终端会话有效。

前后台进程切换

Linux 提供了灵活的机制来在后台和前台之间切换进程:

  • 后台运行 (&):在命令末尾加上 & 符号,可以让程序在后台执行,从而释放当前终端供其他操作使用。例如:command &
  • 暂停进程:在前台运行的进程中按下 Ctrl + Z,可以将其暂停(挂起)并放入后台。
  • 后台恢复 (bg):使用 bg %job_number 可以让一个被暂停的后台任务继续在后台运行。
  • 前台恢复 (fg):使用 fg %job_number 可以将后台任务(无论是运行中还是暂停状态)调回前台继续执行。

杀死进程 (kill 命令)

当需要强制终止一个进程时,可以使用 kill 命令。它通过向进程发送信号(Signal)来实现控制:

  • 常规终止kill PID(默认发送 SIGTERM 信号,允许进程进行清理后退出)。
  • 强制终止kill -9 PID(发送 SIGKILL 信号,强制立即终止进程,进程无法捕获或忽略该信号)。

4. 进程三态图

进程在生命周期中会在以下三种基本状态之间转换:

  1. 运行态(Running):进程正在 CPU 上执行指令。
  2. 就绪态(Ready):进程已具备运行条件,正在等待 CPU 的调度分配。
  3. 阻塞态(Blocked / Waiting):进程因等待某个事件(如 I/O 操作完成、等待信号量等)而暂时无法执行。

状态转换逻辑

  • 就绪态 → 运行态:被操作系统调度程序选中,分配 CPU。
  • 运行态 → 就绪态:时间片用完或被更高优先级的进程抢占。
  • 运行态 → 阻塞态:主动请求 I/O 或等待某事件。
  • 阻塞态 → 就绪态:等待的事件已完成,重新具备运行条件。

5. 核心系统调用

  • 在 C 语言中,Linux 通过以下系统调用来实现进程的创建、执行与同步。

    5.1 fork():创建新进程

    pid_t fork(void);
    
    • 函数作用
      通过复制当前进程(父进程)创建一个几乎完全相同的新进程(子进程)。子进程拥有独立的 PID、独立的内存空间(写时复制 COW),但继承了父进程的文件描述符、环境变量等。

    • 参数:无。

    • 返回值(关键)

      • 父进程中:返回 子进程的 PID(大于 0)。
      • 子进程中:返回 0
      • 失败时:返回 -1,并设置 errno
    • 代码逻辑示例

      pid_t pid = fork();
      if (pid < 0) { /* 错误处理 */ }
      else if (pid == 0) { /* 子进程执行逻辑 */ }
      else { /* 父进程执行逻辑 */ }
      

    5.2 execlp():执行新程序

    int execlp(const char *file, const char *arg, ... /* (char *) NULL */);
    
    • 函数作用
      用参数指定的新程序替换当前进程的映像。调用成功后,原进程代码不再执行,而是从新程序的 main 开始;若失败则返回 -1。

    • 参数详解

      1. file:要执行的可执行文件名。p 后缀表示会在环境变量 PATH 中自动搜索路径。
      2. arg:新程序的参数列表。第一个参数必须是文件名本身(即 argv[0])。
      3. ...:后续参数,必须以 (char *)NULL 结尾
    • 示例

      // 相当于执行: ls -l /home
      execlp("ls", "ls", "-l", "/home", (char *)NULL);
      

    5.3 wait():回收子进程

    pid_t wait(int *status);
    
    • 函数作用
      父进程调用后会阻塞,直到任意一个子进程终止。用于获取子进程退出状态并释放其内核资源,防止僵尸进程
    • 参数详解
      • status:若非NULL,内核会将子进程的退出状态写入该整型变量。
        • 需使用宏解析:WIFEXITED(status) 判断是否正常退出,WEXITSTATUS(status) 获取退出码。
        • WIFSIGNALED(status) 为真,则子进程被信号杀死,用 WTERMSIG(status) 获取信号值。
    • 返回值
      • 成功:终止子进程的 PID
      • 失败:-1(如没有子进程时返回 ECHILD)。

    5.4 waitpid():精确等待

    pid_t waitpid(pid_t pid, int *status, int options);
    
    • 函数作用
      wait() 的增强版,支持等待指定子进程,且支持非阻塞模式。
    • 参数详解
      1. pid:
        • > 0:等待指定 PID 的子进程。
        • -1:等待任意子进程(等同于 wait())。
        • 0:等待同进程组的任意子进程。
        • < -1:等待指定进程组的任意子进程。
      2. status:同 wait(),用于存储退出状态。
      3. options:
        • 0:阻塞等待(同 wait())。
        • WNOHANG非阻塞。若指定子进程未结束,立即返回 0,不挂起父进程。
    • 返回值
      • > 0:终止子进程的 PID。
      • 0:使用了 WNOHANG 且子进程尚未结束。
      • -1:出错。

    5.5 system():Shell 命令执行

    int system(const char *command);
    
    • 函数作用
      高级库函数,内部封装了 fork() + execl("/bin/sh", ...) + waitpid()。用于在 Shell 中执行字符串命令。
    • 参数详解
      • command:Shell 命令字符串(如 "ls -l | grep txt")。
      • 若为 NULL,用于检测系统是否存在 Shell。
    • 返回值
      • command 为 NULL:非 0 表示有 Shell 可用。
      • 执行成功:返回命令的退出状态(需 WEXITSTATUS 解析)。
      • 执行失败/Shell 不存在:返回 -1127
      • 安全警告
        严禁在 Set-UID 程序或不可信输入中使用 system(),极易导致命令注入漏洞。生产环境应优先使用 fork() + exec 家族。

    核心函数对比总结

    函数 核心作用 是否阻塞 关键特性
    fork 复制进程 一次调用,两次返回
    execlp 替换进程映像 成功不返回,失败才返回
    wait 回收任意子进程 防止僵尸,获取退出码
    waitpid 回收指定子进程 可控 支持 WNOHANG 非阻塞
    system 执行 Shell 命令 方便但开销大,有安全风险
posted @ 2026-07-05 17:52  Solitude0420  阅读(27)  评论(9)    收藏  举报