Linux进程的几种状态(一)

本文详细介绍了Linux系统中进程的六种状态,包括运行或可运行状态(R)、可中断的睡眠状态(S)、不可中断的睡眠状态(D)、暂停或跟踪状态(T)、僵死状态(Z)以及退出状态(X)。并通过网易校招笔试题的形式,帮助读者理解进程的基本状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Linux系统是一个多用户、多任务的操作系统,它可以同时运行多个用户的多个程序,就必然会产生很多的进程,而不同的进程一般有不同的状态。

下面是网易校招的笔试题
Linux下的进程有哪3种状态?( )
  A 精确态,模糊态和随机态
  B 运行态,就绪态和等待态
  C 准备态,执行态和退出态
  D 手动态,自动态和自由态

答案为B选项

实际上Linux系统中进程的状态分为R、S、D、T、Z和X 6种状态。

1.R Running or runnable(on run queue)

  处于运行或能(可)运行状态,即进程正在运行或在运行队列(可执行队列)中等待。只有在该状态的进程才可能在CPU上运行,同一时刻可能有多个进程处于该状态。【ps:很多教科书上将正在CPU上执行的进程的状态定义为Running,将可执行但尚未被调度执行的进程状态定义为Ready,这2种状态在Linux下统一为R状态】
  

2.S Interruptible sleep

  处于可中断的睡眠状态,即进程在休眠中,由于在等待某个事件的完成(或等待某个条件的形成或等待某个信号等)【ps:等待socket连接、等待信号量等】而被挂起;当这些事件发生时,对应的等待队列中的一个或多个进程将被唤醒。一般情况下,进程列表中绝大多数进程都处于该状态。
  

3.D Uninterruptible sleep

  处于不可中断的睡眠状态不可中断指的并不是CPU不响应外部硬件的中断,而是指进程不响应异步信号,无法用kill命令杀死,进程必须等待直到有中断发生。
  一般由等待I/O【磁盘I/O、网络I/O和其他外设I/O】引起,同步I/O在做读或写操作时,此进程不能做其他事情,只能等待;如果程序采用异步I/O,这种状态应该就很少被看见了。
  在进程对某些硬件进行操作时(例如进程调用read系统调用对某个设备文件进行读操作),可能需要使用Uninterruptible sleep状态对进程进行保护,以避免进程与设备交互的过程被打断,造成设备陷入不可控的状态。这种情况下Uninterruptible sleep状态非常短暂,通过ps命令基本上不可能捕捉到。
【注】:When the process is sleeping uninterruptibly, the signal will be noticed when the process returns from the system call or trap.

4.T Stopped or Traced

  处于暂停或跟踪状态。进程收到SIGSTOP、SIGSTP、SIGTIN、SIGTOU等信号进入暂停状态(除非进程处于不可中断的睡眠状态);当接着向进程发送1个SIGCONT信号,进程可以从暂停状态恢复到运行或能运行状态。
  当进程被跟踪时,它处于被跟踪状态。“被跟踪”指进程暂停下来,等待跟踪它的进程对它进行操作。例如在GDB调试中,对被跟踪的进程设置某个断点,进程执行到断点处停下来的时候就处于被跟踪状态。
  
【注】:对于进程本身而言,暂停状态和被跟踪状态很类似,都表示进程暂停下来;但被跟踪状态相当于在暂停状态之上多了一层保护,处于被跟踪状态的进程不能响应SIGCONT信号而被唤醒,只能等到调试进程通过ptrace系统调用执行ptrace_cont、ptrace_detach等操作(通过ptrace系统调用的参数指定操作),或调试进程退出,被调试的进程才能恢复到R状态。

5. Z Dead-Exit_Zombie

  处于僵死状态,也称退出状态。它指进程已经结束,放弃了几乎所有的内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置来记载该进程的退出状态等信息(task_struct结构体[保存了该进程的退出码])供其他进程收集

  如果该子进程的父进程没有收到SIGCHLD信号,故未调用wait(如wait4、waitid)处理函数等待子进程结束,又没有显示忽略该信号,该子进程就一直保持僵死状态。只要父进程不退出,这个僵死的子进程就一直存在。多进程写不好的话,这种状态是常见的。
  
  如果该子进程(PID)的父进程(PPID)结束了,则init进程(PID为1)自动接手该子进程,给它收尸。
  当进程退出时,会将它的所有子进程都托管给别的进程(使之成为别的进程的子进程)。托管的进程可能是退出进程所在进程组的下一个进程(如果存在的话)或者是init进程。故每个进程、每时每刻都有父进程存在

  linux系统启动后,第1个被创建的用户态进程就是init进程,它通常有2个作用:
  1.执行系统初始化脚本,创建一系列的进程(都是init进程的子孙);
  2.在一个死循环中等待其子进程的退出事件,并调用waitid系统调用来完成“收尸”工作。

  init进程不会被暂停,也不会被杀死(由内核来保证)。它在等待子进程退出的过程中处于可中断的睡眠状态,“收尸”过程中处于运行状态。
  处理僵死进程的办法:先找出父进程号(PPID),然后kill父进程,之后子进程(僵死进程)被托管到其他进程(如init进程),然后由init进程将子进程的尸体(task_struct)释放掉。

  可以通过如下命令查看僵死进程:ps -ef|grep defunc

6.X Dead-Exit_Dead

  进程在退出过程中可能不会保留它的task_struct。例如某个进程是多线程程序中被detach过的进程;或者父进程通过设置SIGCHLD信号的Handler为SIG_IGN,显示的忽略了SIGCHLD信号。
  此时该进程被置于exit_dead退出状态,这意味着接下来的代码立即会将该进程彻底释放。故exit_dead状态非常短暂,几乎不可能通过ps命令捕捉到。

  再回过头来看网易的那道题,B选项的运行态和就绪态可以统一称为R状态,而等待态则理解为等待/阻塞态,包括S(可中断的睡眠状态)、D(不可中断的睡眠状态)、T(暂停或跟踪状态)、Z(僵死状态)【X状态很短暂,忽略不计】

参考资料

1.Linux进程状态 说明

2.Linux系统的进程通常有以下几种状态

3.Linux下的进程有哪三种状态

4.Linux下进程的各种状态

5.每天一个linux命令(41):ps命令

### Linux 常见的进程状态及其含义 在 Linux 系统中,进程的状态可以通过 `top` 或者 `ps` 命令查看。以下是常见的进程状态以及它们的具体含义: #### 1. 运行状态 (Running, R)进程正在运行或者等待 CPU 间片以便执行,它处于 **运行状态**。这种状态下分为两种情况:实际运行中的进程和准备运行但尚未获得 CPU 的进程[^4]。 #### 2. 可中断睡眠状态 (Sleeping, S) 如果进程无法继续执行而进入休眠模式,则其状态标记为 **可中断睡眠状态**。在这种情况下,进程正等待某些事件的发生(例如 I/O 操作完成)。旦条件满足,进程会被唤醒并恢复到运行状态。 #### 3. 不可中断睡眠状态 (Disk Sleep, D)状态表示进程正处于深度睡眠之中,并且不能被信号打断。通常是因为该进程正在进行重要的硬件操作(比如磁盘读写),直到设备响应为止才会返回正常流程。 #### 4. 停止状态 (Stopped, T/t) 当某个进程接收到 SIGSTOP、SIGTSTP 等暂停信号后就会转变为 **停止状态**。此不会消耗任何 CPU 资源,除非再次受到启动指令才能重新激活成为活动实体;另外还有种特殊情况即调试过程中设置断点所引发的 t 标记形式。 ```bash kill -SIGSTOP <pid> # 发送停止信号给指定 PID 的进程 ``` #### 5. 死亡状态 (Dead, X) 这是短暂过渡阶段,在内核清理完毕之后很快消失不见。般无需特别关注此类状况下的实例存在否即可。 #### 6. 僵死状态 (Zombie, Z) 所谓僵尸进程是指那些已经结束了自己的生命周期但却未完全释放资源的对象——尽管它们实际上不再占用计算能力却仍然保留着唯的标识符(PID),直至父程序调用 wait() 函数回收相关信息为止之前直保持这样的形态存在于系统当中。 #### 7. 孤儿进程 (Orphan Process) 孤儿进程是指它的父进程先于自己终止的情况下的子代单元,默认由 init 进程接管负责后续处理工作以防丢失必要的管理权限[^2]。 #### 8. 特殊标志组合解释 除了上述基础分类之外还有些复合型标签用于提供更多细节描述: - **Ss+**: 表明这是个前台进程中属于会话领导者角色的同也具备较高优先级属性。 - **D+**: 类似常规不可中断态只是额外标注出了当前对象位于前台分组内部位置而已。 - **S<**: 显示出此刻目标拥有高于平均水平调度权值设定情形下呈现出来的外观特征表现出来样子模样如何等等诸如此类现象发生候应该怎样应对办法措施有哪些可供选择考虑采用实施应用实践探索研究学习交流分享讨论共同进步成长发展成就辉煌未来梦想成真愿望达成目的实现目标圆满成功胜利告捷喜讯传来佳音频传好消息不断涌现层出不穷层出不 ### 示例代码展示 下面提供段简单的 Python 脚本用来模拟创建新进程并通过 ps 查看其状态变化过程: ```python import os import time def child_process(): print(f"Child process started with pid {os.getpid()}") while True: pass # Simulate a busy loop to keep the process running. if __name__ == "__main__": pid = os.fork() if pid == 0: # Child process logic. child_process() else: print(f"Forked new process with pid {pid}.") try: input("Press Enter key after checking 'ps' command output...") finally: os.wait() # Wait for child termination before exiting parent. print("Parent process ended.") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值