Linux中进程的状态

进程的状态信息存储在进程的task_struct(PCB)中。
进程状态的意义是方便操作系统快速的判断进程,完成特定的功能,比如调度,其本质是一种分类

下面是Linux内核源码对状态的定义 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
};

R.运行状态

当进程要运行就需要把进程加载到CPU中,而计算机的CPU资源是有限的,进程可能有很多,所以进程可能会等待CPU资源,拿我们就需要一个队列来管理在等待CPU资源的进程,这个队列叫做运行队列在运行队列中等待的进程所处的状态就是运行状态
在这里插入图片描述
所以当一个进程处于运行状态时并不代表该进程就在占用CPU资源,只是当前进程被放在了运行队列中,随时可供CPU调度。
演示代码

while(true)
{
	std<<cout"I am a process"<<std::endl;
}

让一个进程不断的打印一句话,其现象为:
在这里插入图片描述
一种在运行的程序,按理说应该是R状态,但起始它大部分时间都是S状态,因为显示器的速度比较慢,所以在打印的时候可能会进入等待状态,所以一般大部分时候都是S状态,少部分是R状态。

这里状态后面带的+号表示进程是在前台运行的,不带+号则表示在后台运行,假设我的程序名叫做myproc。
./myproc(直接在当前目录下运行,是前台进程,运行时可以输入命令,也就可以用ctrl+c杀掉该进程)
./myproc&(在运行命令后面加&,是后台进程,无法输入命令,也就不能用ctrl+c杀掉进程,只能向进程发送9号信号杀掉进程)

S.睡眠状态/D.磁盘休眠状态

进程并不是只会等待CPU资源,当进程想要完成某种任务时,可能会出现任务条件不具备的情况,那这时进程就需要等待这些其他资源就绪,就会进入S或D状态,与运行状态类似,等待的进程也需要一个队列对其进行管理,进程等待CPU资源时叫做运行队列,等待其他资源时就叫做等待队列
在这里插入图片描述
进程在运行时,有可能因为运行的需要,会处在不同的队列里,而在不同的队列所处的状态就是不一样的,这也就是状态本质是一种分类的体现。

我们把进程从运行队列中放到等待队列中的过程叫做挂起等待(阻塞)从等待队列放到运行队列的过程叫做被CPU调度唤醒进程

S状态与D状态的区别:
S状态也叫可中断睡眠,是浅度睡眠
D状态也叫不可中断睡眠,是深度睡眠
进程如果处于D状态,那么这个进程就不能被kill掉,因为它不再响应异步信号。想要干掉这个进程,只能等进程完成或者电脑重启。

T.暂停状态

进程处于暂停状态,此时信息没有任何更新,是完全的暂停。与S状态的区别是S状态还会有一些数据更新,比如睡眠了多少秒等。

可以用命令kill -l查看信号
在这里插入图片描述
18号信号让进程变成T状态,可以用命令(kill -18 “进程的PID”)向进程发送该信号。
19号命令让进程从T状态恢复,可以用命令(kill -19 “进程的PID”)向进程发送该信号
在这里插入图片描述
通过向进程发送18号信号,让进程进入了T状态,发送19号信号,进程又回到了R,S状态,但是这时候的进程状态后面没有+号,代表是后台进程,所以只能向进程发送9号信号杀掉进程。
在这里插入图片描述

t.追踪状态
也是一种暂停,是我们控制进程一步一步的执行,就像我们的调试过程。

X.死亡状态

CPU会回收进程的资源,包括基础相关的内核数据结构(PCB)+代码和数据,相当于进程彻底的没了。

Z.僵尸状态

在进程死亡时,其父进程会对其进行资源回收,如果没有进行资源回收的进程退出就会进入Z状态,这时的进程就叫做僵尸进程
下面是代码演示

#include <iostream>
#include <unistd.h>
int main()
{
	pid_t id=fork();
	if(id==0)//子进程
	{
		while(true)
		{
			std::cout<<"child is running"<<std::endl;
			sleep(1);
		}
	}
	else if(id>0)//父进程
	{
		std<<cout<<"parent is running"<<std::endl;
		sleep(20);
	}
	return 0;
}

我们可以用上面的进程检测脚本检测我们的进程。
让父进程运行20秒,子进程不断的运行,这时候我们把子进程kill掉,可以发现子进程的状态变成了Z,因为父进程还没有运行结束,子进程被kill了,就没有回收它的资源,所以变成了僵尸进程
在这里插入图片描述
如果我们让这个代码一种运行下去,20秒后子进程还没有结束它的父进程就已经结束了,那么这个子进程会被1号进程(也就是操作系统)领养,叫做孤儿进程

在这里插入图片描述

总结

当进程开始运行,首先会对进程进程初始化,当初始化完成时进程就会进入就绪状态,在运行队列中等待CPU的调度,当时间片来了进程就被加载到CPU中运行,这时的进程属于运行态,时间片到了进程就再次被放入运行队列,回到就绪态,运行态和就绪态加起来属于R状态。
进程在R状态时可能会因为信号或者事件而需要进行等待,这时的进程就属于挂起等待或者阻塞,其状态可能是S,D,T中的一种,当等待结束后,进程又会回到R状态中的就绪态开始执行。
当程序运行完成结束时,进程就会进入Z,X状态,直到资源被回收,运行完毕。
在这里插入图片描述

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Linux,可以使用ps命令来查看进程状态。ps命令是最基本同时也是非常强大的进程查看命令,可以确定有哪些进程正在运行和运行的状态进程是否结束、进程有没有僵死、哪些进程占用了过多的资源等等。可以使用不同的选项来获取不同的进程信息。例如,使用ps命令的a选项可以显示当前终端下的所有进程信息,包括其他用户的进程;使用u选项可以以用户为主的格式输出进程信息;使用x选项可以显示当前用户在所有终端下的进程。\[1\]另外,还可以使用top命令来查看进程的动态信息,该命令可以显示进程信息的动态变化。\[1\]如果需要终止某个进程,可以使用kill命令,例如使用kill -9 pid来杀死进程。\[3\] #### 引用[.reference_title] - *1* *3* [Linux查看进程状态信息](https://blog.csdn.net/qq_26519945/article/details/107795528)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [LINUX查看进程的4种方法(小结)](https://blog.csdn.net/zong596568821xp/article/details/123211238)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

c铁柱同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值