一个进程通过调用fork()可以创建一个新进程,原进程叫做父进程,新创建的进程叫做子进程。我们知道父进程创建子进程往往不希望子进程跟父进程做同样的事儿,即执行同样的代码。所以当调用fork()函数分流以后只要让子进程调用exec()函数,替换了子进程的代码,子进程便会执行新的代码!
那么,当子进程执行完代码退出后,父进程应该读取子进程的退出状态,即看看子进程的运行结果(保存在子进程的PCB中),不然父进程创建了子进程却并不关心它的任何信息有何意义呢? 可是如果父进程没有及时地读取子进程的退出状态,那么子进程会如何呢?此时子进程就会变成僵尸进程!!! 就像领导交代你做一件事儿一样,他肯定会让你给他汇报工作的完成结果。此时如果他很忙,没空听你面述的话,他应该会让你把工作总结发到他邮箱,方便他查看。那么如果他忘记查看你发的工作总结的话,收件箱肯定会一直存有那个工作总结。日积月累,给他发邮箱的人特别多,那么他收件箱里边的东西也会越来越多,直到上限。由此,我们便可以知道,如果僵尸进程一直存在的话,便会造成内存泄漏!!!
总结一句话就是,如果子进程比父进程先退出,而父进程没有及时读取子进程的运行结果,那么子进程便会变成僵尸进程!!!
那么我们该如何处理所产生的僵尸进程呢?
kill指令:给某个进程发送某个特定信号,发送一个特定信号就能完成进程的销毁。
但是,直接kill僵尸进程是不能销毁僵尸进程的。但是我们可以从创建它的父进程着手,如果父进程被kill了,那么子进程也会被销毁
此时很多人可能心有疑惑,既然是因为子进程先于父进程退出,而父进程没有关心子进程的退出状态,所以子进程才会变成僵尸进程。而为了不让内存有泄漏的危险,在父进程并没有读取子进程运行结果的情况下,我们将父子进程一起销毁了,这样做有什么意义呢?如果父进程创建子进程只是为了让子进程变成僵尸进程的话,何必呢。
所以我们应该让父进程创建了子进程之后,当子进程先于父进程退出后,及时地读取子进程的退出状态。这样子进程被创建了才有它存在的意义。那么如果做到呢? >> 进程等待