孤儿进程与僵尸进程

1.基本概念

在Unix系列的进程管理中,子进程是由父进程通过fork()函数向内核申请开启子进程,而内核在开启子进程时子进程时内存数据会copy父进程的内存数据。

所以子进程或父进程运行过程是完全独立的,父进程并不知道子进程的运行状态,当某个进程结束时它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。

孤儿进程:某个父进程退出而它的子进程并没有退出,这些子进程就被称为孤儿进程而内核会将这些子进程的父进程设置成init(进程号1)这个守护进程,并有init通过wait()或者waitpid()系统调用来获取进程终止状态

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

任何一个子进程退出以后都会变成僵尸进程保留一些信息的存在,父进程处理后才能真正是否该进程,当子进程处于僵尸状态时通过ps -aux看到的子进程状态"z",

在父进程运行过程中内核提供一种机制让父进程知道子进程结束时的状态信息

系统机制:在每个进程退出时内核会释放进程的资源包括文件句柄 占用的内存等,但会保留一个状态信息包括(进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等),直到父进程通过wait或waitpid系统调用获取子进程处于结束运行状态时该信息才会被释放

2.父进程的状态

调用wait()或waitpid()的父进程会发生什么情况:
1. 如果有子进程都还在运行则阻塞;
2.如果是一部分子进程终止,而另一部分还在运行,不会被阻塞只要有一个进程终止,wait就会返回。也就是说只要wait接收到一个SIGCHLD信号,wait()就会返回。对于两个或多个子进程的情况,需要调用wait两次或多次
3. 如果一个子进程已经终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回;
4. 如果它没有任何子进程,则立即出错返回;

3.僵尸进程的危害及处理思路

如果子进程一直处于僵尸进程就导致了进程号一直被占用,但系统的进程号是有限的(65535)如果一个系统产生了大量的僵尸进程那么将会导致系统不能正常的产生新的进程

而孤儿进程虽然没有了父进程,没当出现一个孤儿进程内核会自动的将该进程的父进程设置为init这个守护进程,而init进程会循环的通过wait()退出子进程,所以孤儿进程并没有什么危害

我们在操作系统中发现大量的僵尸进程我们应该怎么处理呢?

1.我们知道僵尸进程并不是危害的根源,因为每个子进程在结束时都会变成一个僵尸进程等待父进程释放资源

2.如果一个父进程只大量的产生子进程而对子进程的状态不跟进,那么这些子进程就会一直处于僵尸进程状态

3.我们应该找到这些僵尸进程的父进程kill掉,那么这些僵尸进程会自动变成孤儿进程,内核会将这些进程交给init处理来释放他们的资源

参考文章

1.https://www.cnblogs.com/Anker/p/3271773.html

2.https://www.cnblogs.com/black-mamba/p/6886434.html

原文地址:https://www.cnblogs.com/imgolang/p/10186211.html