ll -18 (进程PID)
注意
进程继续在运行了。但是我们发现有一个地方好像和之前不一样了,S后面是不是一直有一个+号来着?我们也不知道+是干嘛的,只知道他现在好像消失了。
- “+” 代表在前台运行,没有”+“表示在后台运行;
之前我们在终止一个程序时,习惯使用Ctrl + c ,但是现在好像对于后台在运行的进程失效了,此时我们需要掌握一条新的指令来”杀掉“进程:
或者,
X状态与Z状态
- X状态为退出状态是一个瞬时状态不易观察,暂且认为它不重要;
- Z状态被称为僵尸状态。顾名思义,一个进程死了(退出了)但没有”收尸“,就成了”僵尸“。具体一点,当一个进程退出时如果它的父进程没有读取到该进程退出时返回的退出状态码,该进程就会变成僵尸进程。
概念有点多,先来理一理。首先什么是退出状态码?在一段C语言程序中,我们经常要在main函数结束时写一句代码——return 0; 。这个0就是退出状态码,但并不仅仅是0,还可以是1,2,3…
如何看到僵尸进程?
接下来我们就写一段代码看看僵尸进程:
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t id = fork();
if(id == 0)
{
while(1)
{
printf("我是子进程,我在运行,pid:%d,ppid:%d\n",getpid(),getppid());
sleep(1);
}
}
else if(id > 0)
{
while(1)
{
printf("我是父进程,我在运行,pid:%d,ppid:%d\n",getpid(),getppid());
sleep(1);
}
}
return 0;
}
当我们运行程序后,能看到程序正常的在运行;
此时当我们执行指令将子进程”杀“掉,子进程就会变成僵尸进程;
其中我们能看到一个英文单词——defunct就是僵尸的意思。
僵尸进程的危害
- 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(即PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护。
- 一个父进程创建了很多子进程,就是不回收,就会造成内存资源的浪费。因为数据结构对象本身就要占用内存。
僵尸进程是有危害的,当然我们也可以避免它,这就需要在下一章节中提到了。
孤儿进程
当父进程活着,子进程提前挂掉,容易造成僵尸进程。那如果父进程提前挂掉,子进程又该何去何存呢?这就是我们接下来要讲的孤儿进程了。
如何看到孤儿进程
编辑如下代码:
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t id = fork();
if(id == 0)
{
while(1)
{
printf("我是子进程,我在运行,pid:%d,ppid:%d\n",getpid(),getppid());
sleep(1);
}
}
else if(id > 0)
{
while(1)
{
printf("我是父进程,我在运行,pid:%d,ppid:%d\n",getpid(),getppid());
sleep(1);
}
}
return 0;
}
运行该程序,我们使用kill命令”杀“掉父进程,此时再来查看进程信息:
如上图所示,子进程发生了两个变化。一是子进程的PPID,二是子进程变为在后台运行了。
如何理解
当子进程的父进程挂掉之后,子进程会被1号进程领养。该进程也被称为孤儿进程。
答案是,找一个人为自己收尸。不然当哪一天自己突然挂掉,没人为自己收尸那么就会变成为祸人间的僵尸进程了。
点击关注,第一时间了解华为云新鲜技术~