Linux - 进程状态

文章目录

进程状态

进程状态概述

基本状态

  • 创建状态:进程正在被创建,操作系统为其分配资源(如内存、PCB 等),初始化相关信息。
  • 就绪状态:进程已具备运行条件,等待 CPU 调度执行。
  • 运行状态:进程正在 CPU 上执行指令。
  • 阻塞状态:进程因等待某些事件(如 I/O 完成、信号等)而暂停执行,直到事件发生后才能继续运行。
  • 结束状态:进程已完成执行或被强制终止,操作系统回收其资源。

挂起状态(为解决内存等资源限制引入,将部分进程暂时调出内存)

  • 挂起就绪状态:进程已具备运行条件,但因内存等资源限制被调出内存,等待重新调入内存后才能运行。
  • 挂起阻塞状态:进程因等待某些事件而暂停执行,同时被调出内存,等待事件发生并重新调入内存后才能继续运行。

核心进程状态(5种基础状态)

状态标识 英文名称 中文名称 核心含义
R Running/Runnable 运行 / 可运行态 进程正在 CPU 上运行,或已就绪等待 CPU 调度(处于内核的运行队列中)
S Interruptible Sleep 可中断睡眠态 进程因等待可中断资源(如 I/O 完成、信号、等待锁释放)而暂停,收到信号后可被唤醒。
D Uninterruptible Sleep 不可中断睡眠态 进程因等待不可中断资源(如磁盘 I/O、硬件操作)而暂停,任何信号都无法唤醒,只能等待资源就绪。
T Stopped/Trace 停止 / 追踪态 进程被暂停(如收到SIGSTOP、SIGTSTP信号),或被调试器(如gdb)追踪(T标识)。
Z Zombie 僵尸态 进程已终止(代码执行完毕),但父进程未调用wait()/waitpid()回收其 PCB(进程控制块),内核仅保留少量信息(PID、退出状态)。

下⾯的状态在kernel源代码⾥定义:

cpp 复制代码
static const char *const task_state_array[] = {
    "R (running)", /*0 */运行态
    "S (sleeping)", /*1 */可中断睡眠态
    "D (disk sleep)", /*2 */不可中断睡眠态
    "T (stopped)", /*4 */停止态
    "t (tracing stop)", /*8 */追踪态
    "X (dead)", /*16 */死亡态
    "Z (zombie)", /*32 */僵尸态
};  

进程状态查看

复制代码
ps aux / ps axj 命令
示例:  
while :
do
    ps axj | head -1    # 输出进程列表标题行
    ps axj | grep 进程名  # 筛选目标进程
    sleep 1             # 暂停1秒
done 

示例:

  • 查看R状态
cpp 复制代码
int main()
{
    int number = 1;
    while (number++)
    {
        /* code */
    }
    
    return 0;
}  
  • 查看S状态
cpp 复制代码
int main()
{
    int numeber = 0;
    scanf("%d", &numeber);    
    return 0;
}  
  • 查看T状态
    在运行进程时按ctrl + z 可观察到

Z(zombie)-僵⼫进程

  • 僵尸状态(Zombies)是⼀个⽐较特殊的状态。当进程退出并且⽗进程没有读取到⼦进程退出的返回代码时就会产⽣僵⼫进程
  • 僵尸进程会以终⽌状态保持在进程表中,并且会⼀直在等待⽗进程读取退出状态代码。
  • 所以,只要⼦进程退出,⽗进程还在运⾏,但⽗进程没有读取⼦进程状态,⼦进程进⼊Z状态
    示例代码:
cpp 复制代码
int main()
{
    pid_t id = fork();
    if (id < 0)
    {
        perror("fork");
        return 1;
    }
    else if (id > 0)
    { // parent
        printf("parent[%d] is sleeping...\n", getpid());
        sleep(30);
    }
    else
    {
        printf("child[%d] is begin Z...\n", getpid());
        sleep(5);
        exit(EXIT_SUCCESS);
    }
    return 0;
}  


僵⼫进程危害

  • 进程的退出状态必须被维持下去,用于告诉父进程子进程的退出信息,⽗进程如果⼀直不读取,那⼦进程就⼀直处于Z状态
  • 维护退出状态本⾝就是要⽤数据维护,也属于进程基本信息,所以保存在task_struct(PCB)。因此,Z状态⼀直不退出,PCB⼀直都要维护
  • ⼀个⽗进程多个⼦进程,就是不回收,就会造成内存资源的浪费。因为数据结构对象本⾝就要占⽤内存。
  • 内存泄露

孤儿进程

  • 若父进程先于子进程退出,子进程会成为 "孤儿进程"。此时,操作系统会将孤儿进程交由 1 号进程(init或systemd,取决于系统版本)接管 ------ 即 1 号进程成为孤儿进程的新父进程
  • 当孤儿进程后续退出并进入僵尸状态(Z)时,由于其新父进程是 1 号进程,而 1 号进程会周期性地调用wait()系列函数回收所有子进程的资源,因此僵尸状态的孤儿进程会被 1 号进程及时清理,不会长期滞留系统中。
  • 这种机制保证了即使原父进程异常退出,其子进程的资源也能被系统妥善回收,避免僵尸进程堆积。
    代码示例:
cpp 复制代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
    pid_t id = fork();
    if (id < 0)
    {
        perror("fork");
        return 1;
    }
    else if (id == 0)
    { // child
        printf("I am child, pid : %d\n", getpid());
        sleep(10);
    }
    else
    { // parent
        printf("I am parent, pid: %d\n", getpid());
        sleep(3);
        exit(0);
    }
    return 0;
}  


相关推荐
Amazing_Cacao4 小时前
CFCA精品可可产区风土体系(亚洲):彻底拒绝应试背诵,将感官复核作为检验真实物理差异的唯一铁律
学习
FoldWinCard5 小时前
D5 Linux 网络及端口命令
linux·运维·服务器
零涂毕业设计6 小时前
毕业设计模块开发-OLED显示屏(IIC协议0.96寸)STM32 ESP32 FPGA Linux驱动免费分享
linux·stm32·单片机·嵌入式·esp32·fpga·oled
tedcloud1237 小时前
OmniRoute怎么部署?开源AI模型路由平台Linux部署教程
linux·服务器·人工智能·开源·音视频
霸道流氓气质7 小时前
KMS 密钥管理服务(Key Management Service)原理与实践
linux·服务器·数据库
SakitamaX7 小时前
LVS(Linux Virtual Server)概念详解
linux·运维·lvs
小张同学a.7 小时前
Linux系统管理
linux·运维
阿龙的工作记录8 小时前
深入理解Linux设备驱动模型
linux·嵌入式硬件·工作记录
代码村新手8 小时前
Linux的基本指令
linux·运维·服务器
hkj88088 小时前
Ubuntu 切换java版本
java·linux·ubuntu