僵尸进程和孤儿进程
2012-04-17 11:24
323 查看
僵尸进程:一个子进程在其父进程还没有调用wait()或waitpid()的情况下退出。这个子进程就是僵尸进程。
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
僵尸进程将会导致资源浪费,而孤儿则不会。
每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init来接管他,成为他的父进程。
一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)。直到父进程通过wait
/ waitpid来取时才释放. 但这样就导致了问题,如果你进程不调用wait / waitpid的话, 那么保留的那段信息就不会释放,其进程号就会一定被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免.
僵尸进程的避免
1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起
2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后, 父进程会收到该信号,可以在handler中调用wait回收
3. 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD, SIG_IGN) 通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父进程发送信号
4. 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一 个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收 还要自己做。
子进程结束后为什么要进入僵尸状态?
因为父进程可能要取得子进程的退出状态等信息。
僵尸状态是每个子进程比经过的状态吗?
是的。任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。这是每个子进程在结束时都要经过的阶段。
例子:
对于父进程,fork函数返回了子程式的进程号,而对于子程式,fork函数则返回零。这样,对于程序,只要判断fork函数的返回值,就知道自己是处于父进程还是子进程中。
到底哪个进程先被调度也不知道.这也是系统内部的事情 。
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
僵尸进程将会导致资源浪费,而孤儿则不会。
每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init来接管他,成为他的父进程。
一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)。直到父进程通过wait
/ waitpid来取时才释放. 但这样就导致了问题,如果你进程不调用wait / waitpid的话, 那么保留的那段信息就不会释放,其进程号就会一定被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免.
僵尸进程的避免
1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起
2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后, 父进程会收到该信号,可以在handler中调用wait回收
3. 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD, SIG_IGN) 通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父进程发送信号
4. 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一 个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收 还要自己做。
子进程结束后为什么要进入僵尸状态?
因为父进程可能要取得子进程的退出状态等信息。
僵尸状态是每个子进程比经过的状态吗?
是的。任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。这是每个子进程在结束时都要经过的阶段。
例子:
#include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> main() { pid_t pid; pid = fork(); if(pid < 0) printf("error occurred!"n"); else if(pid == 0) { sleep(6); printf("I'm a orphan"n"); exit(0); } else { sleep(1); printf("Children Bye!"n"); } } # ./a.out //运行程序的一条命令 Children Bye! # I'm a orphan
对于父进程,fork函数返回了子程式的进程号,而对于子程式,fork函数则返回零。这样,对于程序,只要判断fork函数的返回值,就知道自己是处于父进程还是子进程中。
到底哪个进程先被调度也不知道.这也是系统内部的事情 。
相关文章推荐
- linux系统编程之进程(三):进程复制fork,孤儿进程,僵尸进程
- 孤儿进程与僵尸进程[总结]
- 孤儿进程与僵尸进程[总结]
- linux 僵尸进程和孤儿进程的简要介绍
- 详解僵尸进程与孤儿进程
- 什么是僵尸进程?孤儿进程
- 进程的状态以及僵尸进程和孤儿进程
- 孤儿进程和僵尸进程
- 孤儿进程和僵尸进程
- 孤儿进程与僵尸进程
- 进程间关系:进程、僵尸进程、孤儿进程、进程组、前台进程组、后台进程组、孤儿进程组、会话、控制终端
- (转载)Linux 僵尸进程与孤儿进程
- linux进程知识 程序存储、crontab、fork与vfork、exec、_exit()、wait()与waitpid()、孤儿和僵尸
- 解析僵尸进程与孤儿进程
- 孤儿进程与僵尸进程
- 孤儿进程和僵尸进程详解
- 浅析三种特殊进程:孤儿进程,僵尸进程和守护进程.
- linux编程---进程---孤儿进程与僵尸进程区别
- linux 孤儿进程和僵尸进程
- Linux之僵尸进程和孤儿进程【总结】