您的位置:首页 > 运维架构 > Linux

linux下的僵尸进程和孤儿进程

2017-04-23 11:43 239 查看

一、什么是僵尸进程和孤儿进程?

僵尸进程:一个进程使用fork创建子进程,如果子进程退出而父进程并没有调用wait或者waitpid获取子进程的状态信息,那么子进程的进程描述符任然保存在系统中,这种进程就被称为僵尸进程。

孤儿进程:如果父进程退出而它的一个或多个子进程还在运行,那么这些子进程就被称为孤儿进程。孤儿进程最终将被init进程(1号进程)所收养,并由init进程完成对它们的状态收集工作。

二、问题以及危害

僵尸进程的危害:

一个进程会定期的产生一些子进程,这些子进程由于处理的事情很少,处理完成后会退出,它的声明周期就很短。但是,这些子进程退出之后它们的状态信息还会保留在系统中,它们的父进程只管生成新的子进程并没有去调用wait或者waitpid去获取子进程的状态信息。系统运行一段时间之后就会有大量的僵死进程,用ps命令来查看的话就会看到许多状态为z的进程。我们要解决的话就只能找到那个产生大量僵死进程的父进程,只有杀死掉那个父进程(通过kill发送SIGTERM或SIGKILL),杀死掉那个父进程之后那些僵死进程就成了孤儿进程,孤儿进程会被init进程接管,init会wait掉这些孤儿进程并且释放它们在系统中占用的资源,这些僵死的孤儿进程就会死去。

缘由:

unix里面有一种机制就是父进程要知道子进程结束时的状态信息,每个进程退出的时候内核会释放的掉这个进程的所有资源(包括打开的文件、占用的内存等等)。但还要保留一部分状态信息(进程号、退出状态、运行的时间等等)直到父进程wait或者waitpid才回去释放。这样的话如果进程不去调用wait或者watpid一些进程的状态信息会一直都在系统里面,这些进程号会一直在系统中间,这些进程号就会一直被占用,由于系统使用的进程号是有限的这样长时间就会导致系统不能产生新的进程。

孤儿进程:

孤儿进程是没有危害的,孤儿进程是没有父进程的子进程,当孤儿进程没有父进程时,内核就会init设置为孤儿进程的父进程,init进程就会调用wait去释放那些已经退出的子进程,当孤儿进程完成其声明周期之后,init会释放掉其状态信息。

每一个进程(init除外)在执行exit之后,不会马上消失会留下一个称为僵尸进程的数据结构来等父进程处理。父进程没有及时处理的话,用ps命令来查看就会发现其状态为“z”。父进程及时处理的话,虽然ps之后状态信息不是“z”但并不等于子进程不经过僵尸状态。

三、查看僵尸进程和孤儿进程

孤儿进程的测试程序如下:



测试结果:



从中我们可以看到子进程3906为孤儿进程,其父进程为1,也就是init进程。

僵尸进程测试程序如下:



测试结果:



子进程会持续10s的僵尸状态。

1)向父进程发送SIGCHILD信号

2)父进程处理SIGCHILD信号

执行exit(0)的信号时根据父进程的状态决定自己的状态

如果父进程已经退出(没有wait),该子进程会称为孤儿进程,init会成为其父进程

如果父进程没有退出也没有wait,那么该进程向父进程发送SIGCHILD信号,进入僵尸状态等待父进程为其收尸,父进程一直没有执行wait,该子进程将会处于僵死状态,父进程到死都没有wait处理,那么zombie将由init成为其父进程释放其系统内的状态信息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux