关于僵尸进程和孤儿进程
2017-05-03 22:16
246 查看
tittle:关于僵尸进程和孤儿进程
进程的几种状态
R状态 进程要么在运行要么在运行队列中。S状态 睡眠状态,进程在等待某事件完成(可被中断)
D状态 不可中断的睡眠状态(通常其在第等待IO结的束)
T状态 被停止的进程 (发送信号SIGSTOP停止进程 SIGCONT让进程继续运行)
X状态 进程已死 已被回收 kernel你的do_exit函数返回的状态。
Z状态 僵尸进程。。。
僵尸进程的产生
“僵尸”进程是什么?通常情况下,僵尸进程的成因是因为该进程已经执行完毕,但是该进程的父进程却无法完整的将该进程结束掉(如果他的父进程没安装SIGCHLD信号处理函数调用wait或waitpid()等待子进程结束,又没有显式忽略该信号,即未接受其退出状态信息,那么它就一直保持僵尸状态),而造成该进程一直存在于内存中。一个进程在调用exit命令结束自己的生命的时候,其实
它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)所以僵尸进程需要父进程彻底结束他。
查看僵尸进程
那么如何查看一个进程是否为僵尸进程呢?ps:将某个时间点的进程运行状态选取下来
ps aux //查看系统所有的进程数据
-A:所有的进程均显示出来
-a:不与terminal有关的所有进程
-u:有效用户相关的进程
-x:通常与a一起使用,可以列出较完整的信息
-l:较长、较详细地将该PID的信息列出
当你获知它是一个僵尸进程后,那么你该如何干掉它呢,那么首先就得了解一下进程的管理。
程序之间的相互管理,是通过给予一个信号来进行管理的
查看信号(signal):
1、man 7 signal
2、kill -l
这里显示的是一些操作进程所需要的信号及其编码。
通常情况下,我们只需记住几个特别重要的信号即可。
1:启动被终止的进程,可让该PID重新读取自己的配置文件
9:强制中段一个进程,如果该进程运行到一半(如vim)会产生.filename.swap的半产品文件
15:正常结束一个进程
18:继续运行该进程
19:暂停一个进程
kill -9 (+进程的pid)可以杀死这个进程
模拟一个僵尸进程
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<unistd.h> 4 #include<errno.h> 5 6 7 void FunTest() 8 { 9 pid_t pid; 10 pid = fork(); 11 12 if(pid < 0) 13 { 14 perror("fork error"); 15 exit(1); 16 } 17 else if(0 == pid) 18 { 19 printf("I am the child process.I am exiting\n"); 20 exit(0); 21 } 22 printf("I am father process.i will sleep two seconds\n"); 23 sleep(2); 24 system("ps -o pid,ppid,state,tty,command"); 25 printf("father process is exiting\n"); 26 } 27 28 int main() 29 { 30 FunTest(); 31 return 0; 32 }
执行结果:43645成为僵尸进程
模拟实现多个僵尸进程
父进程循环创建子进程,子进程退出,造成多个僵尸进程。1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<unistd.h> 4 #include<errno.h> 5 6 7 void FunTest() 8 { 9 pid_t pid; 10 int n = 3; 11 while(n){ 12 n--; 13 pid = fork(); 14 15 if(pid < 0) 16 { 17 perror("fork error"); 18 exit(1); 19 } 20 else if(0 == pid) 21 { 22 printf("I am the child process.I am exiting\n"); 23 exit(0); 24 } 25 else{ 26 sleep(1); 27 continue; 28 } 29 30 } 31 printf("I am father process .I will sleep two second\n"); 32 sleep(2); 33 system("ps -o pid,ppid,state,tty,command"); 34 printf("father process is exting\n"); 35 36 } 37 38 int main() 39 { 40 FunTest(); 41 return 0; 42 }
执行结果:43963 43964 43965三个僵尸进程
僵尸进程解决办法
通过信号量机制子进程退出时向父进程发出SIGCHILD信号。在信号处理函数中调用wait进行处理僵尸进程
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<errno.h> 4 #include<unistd.h> 5 #include<signal.h> 6 #include<sys/wait.h> 7 8 static void sig_child (int signo) 9 { 10 pid_t pid; 11 int status; 12 //deal Jiangshi process 13 while((pid == waitpid(-1,&status,WNOHANG)) > 0) 14 { 15 printf("child %d terminated\n",pid); 16 } 17 } 18 19 int main() 20 { 21 pid_t pid; 22 pid = fork(); 23 signal(SIGCHLD,sig_child); 24 if(pid < 0) 25 { 26 perror("fork error"); 27 exit(1); 28 } 29 else if(0 == pid) 30 { 31 printf("I am the child process. I am exiting\n"); 32 exit(0); 33 } 34 printf("I am the father process. I will sleep two seconds\n"); 35 sleep(2); 36 system("ps -o pid,ppid,state,tty,command"); 37 printf("father process is exiting\n"); 38 return 0;
运行结果:僵尸进程被父进程成功回收。
关于孤儿进程
一个父进程退出后,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<unistd.h> 4 #include<errno.h> 5 6 int main() 7 { 8 int pid = fork(); 9 if(-1 == pid) 10 { 11 perror("fork error"); 12 } 13 else if(0 == pid) 14 { 15 printf("child is %d,father is %d\n",getpid(),getppid()); 16 sleep(2); 17 } 18 else{ 19 printf("father is %d,child is %d\n",getppid(),getpid()); 20 printf("father process is exuted\n"); 21 } 22 return 0; 23 }
僵尸进程危害场景:
例如有个进程,它定期的产生一个子进程,这个子进程需要做的事情很少,做完它该做的事情之后就退出了,因此这个子进程的生命周期很短,但是,父进程只管生成新的子进程,至于子进程 退出之后的事情,则一概不闻不问,这样系统运行上一段时间之后,系统中就会存在很多的僵死进程。倘若用ps命令查看的话,就会看到很多状态为Z的进程。 严格地来说,僵死进程并不是问题的根源,罪魁祸首是产生出大量僵死进程的那个父进程。
那我们该如何消灭系统中大量的僵死进程呢?答案就是把产生大量僵死进程的那个元凶杀掉(也就是通过kill发送SIGTERM或者SIGKILL信号啦)。杀掉元凶进程之后,它产生的僵死进程就变成了孤儿进程,这些孤儿进程会被init进程接管,init进程会wait()这些孤儿进程,释放它们占用的系统进程表中的资源,这样,这些已经僵死的孤儿进程 就能瞑目而去了
相关文章推荐
- 孤儿进程和僵尸进程
- 孤儿进程、僵尸进程
- 僵尸进程和孤儿进程
- 僵尸进程与孤儿进程
- 僵尸进程,孤儿进程,wait,exit,execl等函数使用要点
- 关于linux 僵尸进程
- 关于linux的僵尸进程的产生原因的分析
- 孤儿进程和僵尸进程
- 进程间关系:进程、僵尸进程、孤儿进程、进程组、前台进程组、后台进程组、孤儿进程组、会话、控制终端
- Linux中孤儿进程和僵尸进程的解释
- 僵尸进程和孤儿进程
- linux进程知识 程序存储、crontab、fork与vfork、exec、_exit()、wait()与waitpid()、孤儿和僵尸
- 区别之守护进程 孤儿进程 僵尸进程
- 僵尸进程和孤儿进程 [转]
- 孤儿进程和僵尸进程
- 关于linux 僵尸进程
- 孤儿进程和僵尸进程
- 孤儿进程与僵尸进程【二】
- 僵尸进程与孤儿进程
- 进程间关系:进程、僵尸进程、孤儿进程、进程组、前台进程组、后台进程组、孤儿进程组、会话、控制终端