僵尸进程(Zombie Process):
就是已经结束了的进程,但是没有从进程表中删除。太多了会导致进程表里面条目满了,进而导致系统崩溃,倒是不占用其他系统资源。
在Linux进程的状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。它需要它的父进程来为它收尸,如果他的父进程没安装SIGCHLD信号处理函数调用wait或waitpid()等待子进程结束,又没有显式忽略该信号,那么它就一直保持僵尸状态,如果这时父进程结束了,那么init进程自动会接手这个子进程,为它收尸,它还是能被清除的。但是如果如果父进程是一个循环,不会结束,那么子进程就会一直保持僵尸状态,这就是为什么系统中有时会有很多的僵尸进程。
僵尸进程具体实现操作
1.先创建一个test.c文件,代码如下
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main()
5 {
6 int pid = fork();
7 if(pid == 0)
8 {
9 printf("Is childen!\n");
10 sleep(3);
11 exit(1);
12 }
13 else if(pid > 0)
14 {
15 while(1)
16 {
17 sleep(1);
18 printf("Is parent!\n");
19 }
20 }
21 return 0;
22 }
2.然后创建一个新的终端,IP地址一样
3.输入如下命令:
while :;do ps -aux | grep test | grep -v grep; sleep 1;echo "************";done
这个命令可以每隔一秒就显示一次有关test.c程序的信息。
4.输入命令后,切换到之前的终端,运行test.c文件,再切换回来查看是否变为僵尸进程如下图:
可以看到当三秒之后子进程退出,子进程变为了一个僵尸进程。
孤儿进程
一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
孤儿进程具体实现操作如下
1.先创建一个orphan.c文件,代码如下
4 #include <stdio.h>
5 #include <unistd.h>
6
7 int main()
8 {
9 pid_t pid;
10 pid = fork();
11 if(-1 == pid)
12 {
13 perror("fork");
14 return 1;
15 }
16 if(0 == pid)
17 {
18 int times = 20;
19 while(times--)
20 {
21 printf("子进程:%d\n",times);
22 sleep(1);
23 }
24 printf("子进程死亡\n");
25 }
26 else if(pid > 0)
27 {
28 int time2 = 10;
29 while(time2--)
30 {
31 printf("父进程:%d\n",time2);
32 sleep(1);
33 }
34 printf("父进程死亡\n");
35 }
36 return 0;
37 }
2.同上
3.输入如下命令:
while :;do ps -ef | grep orphan | grep -v grep; sleep 1;echo "*************";done
这个命令大体和上面僵尸进程第三步一样,区别就是用了-ef查看,可以查看父进程pid
4.输入命令后,切换到之前的终端,运行test.c文件,再切换回来查看是否变为僵尸进程如下图:
可以看到子进程一开始的父进程PID是5185,当父进程结束时,子进程的父进程PID变为了1。