进程状态详解

在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 ,实时观察进程状态变化。
相关推荐
山上三树2 小时前
task_struct 详解
运维·服务器·网络
WoY20202 小时前
本地PyCharm配置远程服务器上的python环境
服务器·python·pycharm
oMcLin2 小时前
如何打造Linux运维监控平台:Prometheus + Grafana实战与性能优化
linux·运维·prometheus
木卫二号Coding3 小时前
jupyterlab-安装与启动
linux·运维·服务器
fengyehongWorld3 小时前
Linux logger命令
linux·运维·服务器
一只鹿鹿鹿3 小时前
网络信息与数据安全建设方案
大数据·运维·开发语言·网络·mysql
南知意-3 小时前
GitHub 6K Star! 一款完全免费的音乐播放器,爽听VIP歌曲!
linux·windows·开源·github·开源软件·mac
好好学习啊天天向上3 小时前
最新:ubuntu上源码安装llvm,还没有成功
linux·运维·ubuntu
小宇的天下4 小时前
Calibre nmDRC 运行机制与规则文件(13-2)
运维·开发语言