德惠市城乡建设局网站,《小城镇建设》》杂志社网站,网站上传服务器后台上传资料出错,查询网域名解析概念
在 Unix/Linux 系统中#xff0c;正常情况下#xff0c;子进程是通过父进程创建的#xff0c;且两者的运行是相互独立的#xff0c;父进程永远无法预测子进程到底什么时候结束。当一个进程调用 exit 命令结束自己的生命时#xff0c;其实它并没有真正的被销毁#…概念
在 Unix/Linux 系统中正常情况下子进程是通过父进程创建的且两者的运行是相互独立的父进程永远无法预测子进程到底什么时候结束。当一个进程调用 exit 命令结束自己的生命时其实它并没有真正的被销毁内核只是释放了该进程的所有资源包括打开的文件、占用的内存等但是留下一个称为僵尸进程的数据结构这个结构保留了一定的信息包括进程号 the process ID退出状态运行时间这些信息直到父进程通过 wait()/waitpid() 来取时才释放。这样设计的目的主要是保证只要父进程想知道子进程结束时的状态信息就可以得到
僵尸进程 一个进程使用 fork 创建子进程如果子进程退出而父进程并没有调用 wait 或 waitpid 获取子进程的状态信息那么子进程的进程描述符仍然保存在系统中这种进程称之为僵死进程。孤儿进程 一个父进程退出而它的一个或多个子进程还在运行那么这些子进程将成为孤儿进程。孤儿进程将被 init 进程(进程号为1)所收养并由 init 进程对它们完成状态收集工作。
危害
僵尸进程虽然不占有任何内存空间但如果父进程不调用 wait() / waitpid() 的话那么保留的信息就不会释放其进程号就会一直被占用而系统所能使用的进程号是有限的如果大量的产生僵死进程将因为没有可用的进程号而导致系统不能产生新的进程此即为僵尸进程的危害。
孤儿进程是没有父进程的进程孤儿进程这个重任就落到了 init 进程身上init 进程就好像是一个民政局专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候内核就把孤儿进程的父进程设置为 init而 init 进程会循环地 wait() 它的已经退出的子进程。这样当一个孤儿进程凄凉地结束了其生命周期的时候init 进程就会出面处理它的一切善后工作。因此孤儿进程并不会有什么危害。
解决僵尸进程方案
1方案一 父进程通过 wait 和 waitpid 等函数等待子进程结束但这会导致父进程挂起所以这并不是一个好办法父进程如果不能和子进程并发执行的话那我们创建子进程的意义就没有。同时一个 wait 只能解决一个子进程如果有多个子进程就要用到多个 wait
2方案二通过信号机制
子进程退出时向父进程发送 SIGCHILD 信号父进程处理 SIGCHILD 信号在信号处理函数中调用 wait 进行处理僵尸进程。
3方案三fork两次
原理是将进程成为孤儿进程从而其的父进程变为 init 进程通过 init 进程处理僵尸进程。具体操作为父进程一次 fork() 后产生一个子进程随后立即执行 wait(NULL) 来等待子进程结束然后子进程 fork() 后产生孙子进程随后立即exit(0)。这样子进程顺利终止父进程仅仅给子进程收尸并不需要子进程的返回值然后父进程继续执行。这时的孙子进程由于失去了它的父进程即是父进程的子进程将被转交给Init进程托管。于是父进程与孙子进程无继承关系了它们的父进程均为InitInit进程在其子进程结束时会自动收尸这样也就不会产生僵死进程了
4方案四kill 父进程
严格地来说僵死进程并不是问题的根源罪魁祸首是产生出大量僵死进程的那个父进程。因此当我们寻求如何消灭系统中大量的僵死进程时答案就是把产生大量僵死进程的那个元凶枪毙掉也就是通过 kill 发送 SIGTERM 或者 SIGKILL 信号啦。枪毙了元凶进程之后它产生的僵死进程就变成了孤儿进 程这些孤儿进程会被 init 进程接管init 进程会 wait() 这些孤儿进程释放它们占用的系统进程表中的资源这样这些已经僵死的孤儿进程就能瞑目而去了。