9_Linux学习总结_进程状态_僵尸进程_孤儿进程

Linux进程状态有下面这几种:

R (running)

S (sleeping

D (disk sleep)

T (stopped)

t (tracing stop)

X (dead)

Z (zombie)

该代码的作用就是不停的循环。

现在运行这个项目,来查看进程的状态。

左边正一直在执行while循环,右边查看该进程发现该进程的状态是R。该进程是运行状态。

注意:在Linux中,进程处于就绪队列里就是运行态。书中里的就绪态和运行态在Linux中实现都被归为运行态。

我们可以看到该进程状态是R+,这里的符号+代表该进程在前台运行。

现在我们让该进程在后台运行。

在运行可执行程序的后面加上符号&就可以在后台运行

此时该进程的状态就是R

这时候想要停止该进程运行就执行

c 复制代码
kill -9 进程的pid

来把该进程杀掉

当前代码运行到scanf时,就会等待用户输入。该进程就会被阻塞。此时进程处于S状态

运行代码并查看进程状态

此时观察左边终端可以发现该进程在等待输入。观察右边终端发现该进程处于S状态。

现在来看 T 和 t 状态,都是代表着暂停状态。

先看 t 状态,要想要观察进程的 t 状态需要先让我们的代码文件编译成debug的可执行程序

现在来用gdb来调试代码

现在只是用gdb来调式代码,还没有开始运行。

现在在第8行打一个断点

打完断点之后运行代码,并观察进程状态

此时进程就处于 t 状态,t 被称为被追踪时暂停状态。为什么被叫做被追踪时暂停状态,因为是触发断点时进程状态才会变为t状态,相当于追踪到了该断点。

现在代码的功能是一直打印hello world,运行该代码

观察终端能够发现正在循环打印hello world

现在用键盘按下Ctrl 和 z,观察进程运行的情况和状态

左边终端可以发现该进程被暂停,右边终端显示进程状态为T

T:普通暂停(没被追踪)

t:被追踪时的暂停

现在来看D状态:

如果一个进程处于S状态,那么该进程处于可中断休眠,浅睡眠

什么叫可中断休眠?

如果一个进程处于S状态(阻塞),那么我们可以直接用

c 复制代码
kill -9 进程pid

或者Ctrl + c 来杀掉这个进程。

可中断就是指可以响应,能被杀掉。

运行该程序

可以观察到该进程处于阻塞状态

现在杀掉该进程

发现该进程能被杀掉

D状态是不可中断休眠,深睡眠

为什么需要不可中断休眠呢?

假如先在有个进程要把一个非常重要的数据写入硬盘中,此时该进程处于阻塞状态,需要等待IO操作结束才可以返回运行态。如果这时候内存严重不足。如果该进程处于阻塞(S)状态,也就是可中断休眠。万一操作系统或者用户把该进程直接杀掉。我们就会丢失掉这些严重的数据。这时候就需要D状态,如果该进程是D状态(不可中断休眠),该进程不受理任何杀死指令,操作系统和用户都无法杀掉该进程,只有等IO操作结束。该进程才能响应。

S和D状态都是书中的阻塞状态

现在来看X状态,当进程结束时,进程就处于X状态。无法观察,因为进程结束是一瞬间的事,无法通过指令来捕捉。

最后还剩下一个Z状态也就是僵尸状态。

现在举个例子。

现在处于猴子星球,在你的面前突然有一只猴子死亡。你给猴子警察拨打了电话。此时这个猴子已经死亡。但是猴子警察还需要从这只死掉的猴子尸体上进行相关的检查,来判断这只猴子是自然死亡还是它猴杀害。在猴子警察从猴子尸体身上获取信息时,这段时间猴子处于的状态就是僵尸状态。

用进程来解释就是,Linux操作系统几乎所有的进程都由其父进程创建的。为什么要创建子进程?创建子进程一定是需要子进程完成一些功能,如果不需要子进程完成一些功能那么子进程其实就没有存在的必要。所以现在子进程就是去做某种事,既然子进程去做某种事,那么一定要知道子进程完成的怎么样对吧。所以当一个子进程结束时,代码和数据会被立即释放,但是该子进程的PCB不会立即释放,会先保留直到父进程从子进程的PCB中获取相关状态时,这段时间子进程就处于僵尸状态,此时子进程也被称为僵尸进程。直到父进程获取完子进程的信息之后子进程才会从僵尸状态变为X状态(死亡状态),释放子进程的PCB。

子进程会打印5次"我是子进程..."

打印完之后就结束。

父进程会一直打印"我是父进程...",由于父进程一直在执行打印操作,没有办法执行获取子进程信息。所以当子进程结束时,子进程就会一直处于僵尸状态。

运行代码并观察子进程的状态

能够观察到子进程此时处于僵尸状态。

如果父进程一直没有获取子进程的信息,子进程就会一直处于僵尸状态,子进程的PCB就会一直在内存中,造成内存泄漏

孤儿进程:

父进程比子进程先一步退出,导致子进程没有父进程。此时的子进程就是孤儿进程。但是上面说了,子进程退出后必须由其父进程获取其信息,不然子进程就会一直处于僵尸状态,子进程的PCB就会一直在内存中,造成内存泄漏。所以当子进程的父进程先退出时。子进程会被1号进程领养。这样如果子进程要退出,那么子进程的信息就可以被1号进程获取。子进程就不会一直处于僵尸状态。就不会造成内存泄漏。

上面的代码,子进程会一直循环,父进程先循环5次,然后父进程结束退出。

运行并观察子进程的父进程的pid的变化

可以发现现象就如上面文本所述。

相关推荐
北观止1 小时前
服务器登录脚本
运维·服务器
henry1010102 小时前
利用Python一键创建AWS EC2实例
linux·python·云计算·aws·ec2
春日见2 小时前
commit与fetch
linux·人工智能·算法·机器学习·自动驾驶
Linux运维技术栈2 小时前
禅道一键包:跨服务器迁移 + 迁移至LVM分区 实战运维笔记
运维·服务器·禅道
Quintus五等升2 小时前
深度学习自用笔记
人工智能·笔记·深度学习·学习·机器学习·bert·numpy
acanab2 小时前
ros2 URDF学习
学习
roo_12 小时前
Claude Code教程学习
学习
一匹电信狗2 小时前
【Linux我做主】从 fopen 到 open:Linux 文件 I/O 的本质与内核视角
linux·运维·服务器·c++·ubuntu·小程序·开源
WW、forever2 小时前
【服务器-R环境配置】导出配置文件并重建
运维·服务器·r语言