在Linux中你可能进程听到有僵尸进程,那么究竟什么是僵尸进程,他又是怎样产生的呢?下面我们通过1个例子来说明一下。我们知道退出一个进程用系统调用exit,但是这并不意味着该进程马上就消失了,事实上它还留下了一个被称为僵尸进程(Zombie)的数据结构。在Linux进程的5种状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。从这点来看,僵尸进程虽然有一个很酷的名字,但它的影响力远远抵不上那些真正的僵尸兄弟,真正的僵尸总能令人感到恐怖,而僵尸进程却除了留下一些供人凭吊的信息,对系统毫无作用。也许读者们还对这个新概念比较好奇,那就让我们来看一眼Linux里的僵尸进程究竟长什么样子。当一个进程已退出,但其父进程还没有调用系统调用wait(稍后介绍)对其进行收集之前的这段时间里,它会一直保持僵尸状态,利用这个特点,我们来写一个简单的小程序:#include sys/types.h>#include unistd.h>#include stdio.h>/*下面的程序展示了僵尸进程进程关系:主进程(main) ,主进程创建了父进程之后,就退出了||-父进程 该父进程打印信息之后,一直循环 while(1)||-子进程 该子进程创建之后打印就退出,成为僵死进程,因为他的父进程还在运行*/int main(){/*主进程创建子进程*/pid_t child = fork();/*在子进程中*/if ( child == 0 ){pid_t pid;char *message;int n;printf("fork program starting
");/*子进程再创建子进程*/pid = fork();switch( pid ){case -1:perror("fork failed.
");exit(1);break;case 0:message = "This is the son.
";n = 2;break;default:message = "This is father.
";n = 5;break;}/*父子进程都打印输出*/for (; n > 0; n-- ){puts(message);sleep(1);}if ( pid == 0) /*子进程退出, 成为僵死进程*/exit(0);else /*父进程一直循环*/while(1);}else if ( child > 0) /*在主进程中,主进程退出,剩下了1个子进程和子进程的子进程*/exit(0);}在这个程序中有三个进程,主进程,新进程(父进程)和他的子进程。主进程创建了新进程(父进程)之后立刻就退出了,他的资源会被init进程回收,现在只剩下了新进程(父进程)和它创建的子进程,而这个新进程(父进程)创建的子进程输出了一些信息之后就立刻就退出了,就只剩下了新进程(父进程),可是这个父进程并没有调用wait来回收它创建的子进程(虽然此时他的子进程已经退出了,但是仍在在进程表中占有一席之地,这个需要父进程用wait来回收),而此时此刻,这个父进程仍在死循环中(while(1);),于是他的子进程便成为僵尸进程, 我们用 ps aux就可以看到下面的东西:USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDroot 1923 29.0 0.1 2520 308 pts/4 R 00:41 0:09 ./zombie.oroot 1924 0.0 0.0 0 0 pts/4 Z 00:41 0:00 [zombie.o]第2行的Z以及都表明这([zombie.o])是一个僵尸进程, 它的父进程./zombie.o一直在Running(R),此时的僵尸进程我们已经无法用kill将其杀掉,要想将其杀掉,有两个方法,一个是重启机器,另一个就是变通的方法,杀掉它的父进程,当我们杀掉了它的父进程之后,这个僵尸的父进程就会变为init(所有的进程,当它的父进程被杀掉之后,它父进程的父进程就会接管它,以此类推,直到最后由init来接管它),而init进程是一个系统进程,它每隔一段时间就会用wait来回收这些没有父母的僵尸进程。在这里,当你用kill 1923杀掉它的父进程之后,你再用ps 命令就看不到它了。我们就Linux的发展来看一看僵尸进程:我们知道,Linux和UNIX总有着剪不断理还乱的亲缘关系,僵尸进程的概念也是从UNIX上继承来的,而UNIX的先驱们设计这个东西并非是因为闲来无聊想烦烦其他的程序员。僵尸进程中保存着很多对程序员和系统管理员非常重要的信息,首先,这个进程是怎么死亡的?是正常退出呢,还是出现了错误,还是被其它进程强迫退出的?其次,这个进程占用的总系统CPU时间和总用户CPU时间分别是多少?发生页错误的数目和收到信号的数目。这些信息都被存储在僵尸进程中,试想如果没有僵尸进程,进程一退出,所有与之相关的信息都立刻归于无形,而此时程序员或系统管理员需要用到,就只好干瞪眼了。那么,我们如何收集这些信息,并终结这些僵尸进程呢?就要靠我们下面要讲到的waitpid调用和wait调用。这两者的作用都是收集僵尸进程留下的信息,同时使这个进程彻底消失。所以,防止僵尸进程的方法就是要记得调用系统调用wait及时的将其回收。如果你不及时回收,那么它在系统中就会占用一个进程表项,如果这种僵尸进程过多,最后系统就没有可以用的进程表项,于是也无法再运行其它的程序。Ubuntu安全设置及其工具介绍AIX系统文件安全性方面的几点考虑相关资讯 Linux安全
- 发现针对 Linux 服务器和代码库的 (11/08/2015 09:11:50)
- Linux安全与优化 (12/05/2014 17:04:31)
- 加强 Linux 桌面安全 (08/15/2014 11:36:10)
| - 牢记这七点 让你的Linux服务器变得 (08/12/2015 15:39:07)
- 树大招风,Linux的安全威胁正在不 (08/24/2014 21:44:47)
- GNU/Linux安全基线与加固 (07/22/2014 13:51:21)
|
本文评论 查看全部评论 (0)
评论声明- 尊重网上道德,遵守中华人民共和国的各项有关法律法规
- 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
- 本站管理人员有权保留或删除其管辖留言中的任意内容
- 本站有权在网站内转载或引用您的评论
- 参与本评论即表明您已经阅读并接受上述条款
|
|