在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;
}
三、代码解析
- 新建态: fork() 调用成功后,子进程被创建,操作系统为其分配PID和内存资源,此时子进程处于新建态,等待系统调度。
- 就绪态:子进程创建完成后,进入就绪队列等待CPU调度, /proc 中状态显示为 R (running) (Linux中就绪和运行态统一用R标识)。
- 运行态:子进程获得CPU时间片后,执行计算循环,状态保持 R ,此时进程占用CPU执行指令。
- 阻塞态:调用 sleep(3) 模拟I/O等待,子进程释放CPU,状态变为 S (sleeping) (可中断阻塞态),直到sleep结束才重新进入就绪态。
- 终止态:子进程执行 exit(0) 后,若父进程未调用 wait() 回收,会进入 Z (zombie) 僵尸态;父进程调用 wait(NULL) 后,子进程资源被彻底回收,状态文件消失。
四、编译与运行
- 编译命令: gcc process_state.c -o process_state
- 运行命令: ./process_state
- 额外查看:可在另一个终端执行 ps -aux | grep process_state ,实时观察进程状态变化。