进程状态详解

在Linux环境下,C语言可通过系统调用( fork() 、 wait() 、 sleep() 等)结合 /proc 文件系统模拟并查看进程状态,Linux中进程核心状态主要有运行/就绪态®、阻塞态(S)、僵尸态(Z)、暂停态(T),下面通过代码完整演示进程状态的转换过程,并详细解析各状态含义。

一、进程状态核心定义(Linux)

状态标识 含义 对应经典状态

R Running/Runnable 运行态/就绪态

S Sleeping(可中断) 阻塞态(I/O等待)

D Uninterruptible Sleep 阻塞态(不可中断)

Z Zombie 终止态(过渡)

T Stopped 暂停态

二、C语言代码实现:进程状态模拟

代码通过 fork() 创建子进程, sleep() 模拟阻塞, /proc/[pid]/status 读取进程状态,完整代码如下:

c 复制代码
  
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>

// 从/proc文件系统读取进程状态
void print_process_status(pid_t pid) {
    char status_path[64];
    FILE *fp;
    char line[256];
    // 拼接/proc下的进程状态文件路径
    snprintf(status_path, sizeof(status_path), "/proc/%d/status", pid);
    fp = fopen(status_path, "r");
    if (fp == NULL) {
        perror("fopen failed");
        return;
    }
    // 查找State行,提取进程状态
    while (fgets(line, sizeof(line), fp) != NULL) {
        if (strncmp(line, "State:", 6) == 0) {
            printf("进程(%d)当前状态:%s", pid, line + 7);
            break;
        }
    }
    fclose(fp);
}

// 子进程执行的任务,模拟不同状态转换
void child_process_task() {
    pid_t child_pid = getpid();
    printf("\n子进程(%d):创建完成,进入就绪态\n", child_pid);
    print_process_status(child_pid);

    // 模拟运行态:执行计算操作
    printf("子进程(%d):进入运行态,执行计算任务\n", child_pid);
    long long sum = 0;
    for (long long i = 0; i < 100000000; i++) {
        sum += i;
    }
    print_process_status(child_pid);

    // 模拟阻塞态:sleep模拟I/O等待(释放CPU)
    printf("子进程(%d):进入阻塞态,等待I/O(sleep 3秒)\n", child_pid);
    sleep(3);
    print_process_status(child_pid);

    // 再次进入运行态,完成任务
    printf("子进程(%d):回到运行态,计算结果:%lld\n", child_pid, sum);
    print_process_status(child_pid);

    // 执行完毕,进入终止态(若父进程未回收则为僵尸态)
    printf("子进程(%d):任务完成,进入终止态\n", child_pid);
    exit(0);
}

int main() {
    pid_t pid = fork(); // 创建子进程,子进程进入新建态
    if (pid < 0) {
        perror("fork failed");
        exit(EXIT_FAILURE);
    } else if (pid == 0) {
        // 子进程执行逻辑
        child_process_task();
    } else {
        // 父进程执行逻辑
        printf("父进程(%d):创建子进程(%d),子进程进入新建态\n", getpid(), pid);
        print_process_status(pid);

        // 等待子进程结束,避免子进程变成僵尸态
        wait(NULL);
        printf("\n父进程(%d):子进程已终止,回收其资源\n", getpid());
        // 子进程被回收后,/proc下的状态文件会消失,再次读取会报错
        print_process_status(pid);
    }
    return 0;
}
 
三、代码解析
  1. 新建态: fork() 调用成功后,子进程被创建,操作系统为其分配PID和内存资源,此时子进程处于新建态,等待系统调度。
  2. 就绪态:子进程创建完成后,进入就绪队列等待CPU调度, /proc 中状态显示为 R (running) (Linux中就绪和运行态统一用R标识)。
  3. 运行态:子进程获得CPU时间片后,执行计算循环,状态保持 R ,此时进程占用CPU执行指令。
  4. 阻塞态:调用 sleep(3) 模拟I/O等待,子进程释放CPU,状态变为 S (sleeping) (可中断阻塞态),直到sleep结束才重新进入就绪态。
  5. 终止态:子进程执行 exit(0) 后,若父进程未调用 wait() 回收,会进入 Z (zombie) 僵尸态;父进程调用 wait(NULL) 后,子进程资源被彻底回收,状态文件消失。
四、编译与运行
  1. 编译命令: gcc process_state.c -o process_state
  2. 运行命令: ./process_state
  3. 额外查看:可在另一个终端执行 ps -aux | grep process_state ,实时观察进程状态变化。
相关推荐
_下雨天.5 小时前
LVS负载均衡
服务器·负载均衡·lvs
小成202303202657 小时前
Linux高级02
linux·开发语言
mounter6257 小时前
【硬核前沿】CXL 深度解析:重塑数据中心架构的“高速公路”,Linux 内核如何应对挑战?-- CXL 协议详解与 LSF/MM 最新动态
linux·服务器·网络·架构·kernel
++==7 小时前
Linux 进程间通信与线程同步技术详解:IPC 机制、线程 API、同步工具与经典同步问题
linux
特长腿特长8 小时前
centos、ubantu系列机的用户和用户组的结构是什么?具体怎么配置?用户组权限怎么使用?这篇文章持续更新,帮助你复习linux的基础知识
linux·运维·centos
zzzyyy5388 小时前
Linux环境变量
linux·运维·服务器
pluvium278 小时前
记对 xonsh shell 的使用, 脚本编写, 迁移及调优
linux·python·shell·xonsh
无级程序员8 小时前
centos7 安装 llvm-toolset-7-clang出错的问题解决
linux·centos
kebeiovo8 小时前
atomic原子操作实现无锁队列
服务器·c++
赛博云推-Twitter热门霸屏工具9 小时前
Twitter运营完整流程:从0到引流获客全流程拆解(2026)
运维·安全·自动化·媒体·twitter