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;
}  


相关推荐
徐子元竟然被占了!!5 小时前
Linux-systemctl
linux·数据库·oracle
码界奇点5 小时前
Python从0到100一站式学习路线图与实战指南
开发语言·python·学习·青少年编程·贴图
YJlio7 小时前
Active Directory 工具学习笔记(10.8):AdInsight——保存与导出(证据留存、共享与二次分析)
数据库·笔记·学习
_w_z_j_8 小时前
Linux----mmap
linux
程序员zgh9 小时前
Linux系统常用命令集合
linux·运维·服务器·c语言·开发语言·c++
Bigan(安)9 小时前
【奶茶Beta专项】【LVGL9.4源码分析】09-core-obj_class对象类系统
linux·c语言·mcu·arm·unix
紫郢剑侠9 小时前
飞秋@Windows +iptux@Linux,打造内网跨平台IM环境
linux·运维·服务器·im·qq
保持低旋律节奏9 小时前
linux——调试
linux·运维·服务器
噗噗夹的TA之旅10 小时前
Unity Shader 学习20:URP LitForwardPass PBR 解析
学习·unity·游戏引擎·图形渲染·技术美术
牛奶咖啡1310 小时前
Linux系统故障排查思路实践教程(下)
linux·运维·服务器·su命令切换用户问题解决·文件打开过多问题解决·linux网络故障问题解决·linux故障排查思路