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的变化

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