孤儿进程 僵尸进程 守护进程

 

孤儿进程:

       当父进程A fork方式出子进程 B,一般情况下是父进程的寿命比子进程的长,但是这时候父进程突然停止了。这时候子线程B 就没有了父亲,就由init进程托管(也就是id为1的进程),然后它就成了孤儿进程。但是孤儿进程不占用内存空间,不危害系统

 

僵尸进程:

当父亲A 进程 fork 出 B进程,这时候子进程退出了, 但是并没有通知到父进程,父进程没有调用wait和waitpid的方法获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称为僵尸进程。

 

守护进程:就是比如A守护者B进程, 当B进程退出的时候,A进程也会退出,相当于守护的作用,一般用于监控。 像java的GC就是守护进程来的。

 

 

一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)。在Linux进程的状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。它需要它的父进程来为它收尸,如果他的父进程没安装SIGCHLD信号处理函数调用wait或waitpid()等待子进程结束,又没有显式忽略该信号,那么它就一直保持僵尸状态,如果这时父进程结束了,那么init进程自动会接手这个子进程,为它收尸,它还是能被清除的。但是如果如果父进程是一个循环,不会结束,那么子进程就会一直保持僵尸状态,这就是为什么系统中有时会有很多的僵尸进程。

值得注意的是: 

所有的进程都会有成为僵尸进程的过程,每个进程在终结时都会将自己进程的信息发给父进程,等待父进程来处理,这个等待阶段就是僵尸进程。不同的是,一般的父进程会很快将已经死亡的子进程处理掉,但是父进程没有收到信息,或者陷入死循环不能处理时,这个僵尸进程就永远的挂在系统中,无法处理了。僵尸进程占用一个进程ID号,但没办法释放,这无疑对系统是种危害。

三,孤儿进程 

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

子进程死亡需要父进程来处理,那么意味着正常的进程应该是子进程先于父进程死亡。当父进程先于子进程死亡时,子进程死亡时没父进程处理,这个死亡的子进程就是孤儿进程。

但孤儿进程与僵尸进程不同的是,由于父进程已经死亡,系统会帮助父进程回收处理孤儿进程。所以孤儿进程实际上是不占用资源的,因为它终究是被系统回收了。不会像僵尸进程那样占用ID,损害运行系统。

四,僵尸进程的处理 

得出结论,孤儿进程不会占资源,僵尸进程会占用资源危害系统。我们应当避免僵尸进程的出现。 

解决办法如下: 

1)通过信号机制 

  子进程退出时向父进程发送SIGCHILD信号,父进程处理SIGCHILD信号。调用wait()或者waitpid(),让父进程阻塞等待僵尸进程的出现,处理完在继续运行父进程。 

2)杀死父进程 

当父进程陷入死循环等无法处理僵尸进程时,强制杀死父进程,那么它的子进程,即僵尸进程会变成孤儿进程,由系统来回收。 

3)重启系统 

当系统重启时,所有进程在系统关闭时被停止,包括僵尸进程,开启时init进程会重新加载其他进程。

你可能感兴趣的:(计算机底层基础,孤儿进程,僵尸进程,守护进程)