小伙伴们大家好,本片文章将会讲解 Linux操作系统 进程状态 的相关内容。
如果看到最后您觉得这篇文章写得不错,有所收获,麻烦点赞👍、收藏🌟、留下评论📝。您的支持是我最大的动力,让我们一起努力,共同成长!
文章目录
1. 进程状态介绍
🎧1.1 进程状态介绍🎧
进程的状态指的是 操作系统对进程当前所处的情况或条件的描述。在操作系统中,进程可以处于不同的状态,这些状态反映了进程在其生命周期中的不同阶段或活动。
🎧1.2 Linux OS 中的相关进程状态🎧
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
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 */
};
Linux OS 进程状态的相关解释:
- R 运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
- S 睡眠状态(sleeping):意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))。
- D 磁盘休眠状态(Disk sleep):有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
- T 停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
- X 死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。
🎧1.2 Linux OS 进程状态示意图🎧
2. 详解 Linux OS 的进程状态
🎧2.1 S 状态 与 R 状态🎧
C语言生成的可执行文件以及Linux相关的指令都是进程。在Linux系统中,任何可执行的程序都是以进程的形式在运行。当你在终端上输入一个命令时,例如ls(列出当前目录的文件),操作系统会创建一个新的进程来执行该命令。 同样,当你运行一个由C语言编写的可执行文件时,也会创建一个新的进程来执行该程序。
先看一下如下代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
while (1)
{
printf("I am a process,pid = %d\n",getpid());
}
return 0;
}
采用 gcc 生成可执行文件:
gcc -o testStatus testStatus.c
生成可执行文件示意图:
运行 testStatus 并用以下脚本代码查看进程:
while :; do ps ajx | head -1 && ps ajx | grep testStatus | grep -v grep; sleep 1; done
查看进程状态示意图:
为什么这里会是 S 状态而不是 R 状态呢?
- 当我们在终端输入
./testStatus
的时候,操作系统会生成一个task_struct
的结构体,并将代码和数据加载到内存中; - 由于此代码中有
printf()
函数,需要访问外设; - 在这个过程中,CPU不断将内存中的代码和数据放到寄存器中进行处理,处理完成之后再放回内存(冯诺依曼体系);
- 然而由于显示器的速度是非常慢的,因此CPU在等待显示器响应的时候可能会处于空闲状态,等待显示器资源的释放;
- 因此当
CPU
在等待外设资源的时候,Linux
系统中的进程状态会被标记为“休眠”状态。
S 状态是可以被中断的:
通常情况下 S 状态是可以被
kill
指令终结的,所以 S 状态又叫可中断休眠状态。
kill 指令终结 S 状态示意图:
🎧2.2 T 状态🎧
T 状态表示一个进程被暂停执行, 通常是由父进程直接发起的暂停操作。例如 debug 状态下打断点调试代码就是常见的 T 状态。
生成debug文件:
[dsj@iZf8z7jm5hhjctr4l8jdkoZ lesson13.2]$ gcc -o testStatus.debug testStatus.c -g
用gdb进行调试:
[dsj@iZf8z7jm5hhjctr4l8jdkoZ lesson13.2]$ gdb testStatus.debug
打断点并运行:
(gdb) b 5
Breakpoint 1 at 0x4004f1: file testStatus.c, line 5.
(gdb) r
Starting program: /home/dsj/linux-coding/lesson13.2/testStatus.debug
用以下脚本代码查看进程:
while :; do ps ajx | head -1 && ps ajx | grep testStatus | grep -v grep; sleep 1; done
查看进程状态示意图:
也可以用
kill
指令手动让进程暂停或者继续运行,其中18号是让进程继续,19号是终止进程。
kill -l 查看所有信号:
🎧2.3 D 状态🎧
在Linux系统中, 当系统内存压力非常大时,操作系统有权利根据一定的策略选择杀死一些进程以释放内存空间,从而维持系统的稳定性和可用性。这种行为通常称为"内存压力控制"或"内存压缩",它是Linux内核中的一个重要特性之一。
但是有些进程正在等待硬盘、网络或其他设备的I/O操作完成,但是这些操作可能需要较长时间才能完成,而且在这期间进程无法被中断。
S 状态和 D 状态的区别:
虽然S状态和D状态都表示进程在等待外部事件发生,但它们之间的主要区别在于进程等待事件的特性以及操作系统对其的处理方式。
- S状态(休眠状态):
- S状态表示进程正在等待某个事件发生,这个事件可能是等待I/O操作完成、等待信号量的释放、等待其他进程发送消息等。这种等待可能是可中断的,也就是说,如果进程收到了信号(如SIGKILL)或者等待的事件发生超时,操作系统可以中断等待状态,将进程唤醒并重新调度。
- 在S状态下,进程通常在等待期间不会消耗系统资源(如CPU),而是被挂起,等待事件发生。
- D状态(不可中断的休眠状态,Linux OS 特有的状态):
- D状态也表示进程在等待外部事件发生,通常是等待磁盘I/O操作完成。但是,D状态下的进程是不可中断的,即使接收到了信号(如SIGKILL),操作系统也无法中断进程的等待状态。这是为了确保在某些情况下系统的稳定性,例如当进程正在等待磁盘I/O操作完成时,需要确保这些操作完成后系统状态的一致性和完整性。
- 进程处于D状态时,操作系统无法将其释放或终止,直到等待的事件发生并且进程完成相应的操作。
因此,尽管S状态和D状态都涉及等待外部事件发生,但操作系统对待它们的方式不同。S状态下的进程是可中断的,可以在需要时被操作系统释放或重新调度,而D状态下的进程是不可中断的,通常只有在等待的事件发生后才会被操作系统唤醒。