Chinaunix首页 | 论坛 | 博客
  • 博客访问: 867215
  • 博文数量: 82
  • 博客积分: 2283
  • 博客等级: 大尉
  • 技术积分: 2007
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-15 22:19
文章分类

全部博文(82)

文章存档

2012年(82)

分类: LINUX

2012-07-17 09:46:21

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

在一些程序中经常看见使用两次fork创建子进程,原因如下:

以下摘自《UNIX环境高级编程》

如果一个进程fork一个子进程,但不要它等待子进程终止,也不希望子进程处于僵死状态直到父进程终止,实现这一要求的技巧是调用fork两次。程序如下:

#include "apue.h"
#include

int
main(void)
{
pid_t    pid;

   if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) {        /* first child */
if ((pid = fork()) < 0)
err_sys("fork error");
else if (pid > 0)
exit(0);    /* parent from second fork == first child */


/*
* We're the second child; our parent becomes init as soon
* as our real parent calls exit() in the statement above.
* Here's where we'd continue executing, knowing that when
* we're done, init will reap our status.
*/
sleep(2);
printf("second child, parent pid = %d\n", getppid());
exit(0);
}

if (waitpid(pid, NULL, 0) != pid)    /* wait for first child */
err_sys("waitpid error");

/*
* We're the parent (the original process); we continue executing,
* knowing that we're not the parent of the second child.
*/
exit(0);
}


这个程序的实际是,第一次fork创建子进程A,子进程A调用第二次fork创建孙进程B。然后子进程A退出,父进程使用waitpid收集子进程A的信息。那么B的父进程就变成了init的进程。

init进程会在有子进程退出时调用wait函数。

孤儿进程是因为父进程异常结束了,然后被1号进程init收养。

守护进程是创建守护进程时有意把父进程结束,然后被1号进程init收养。
虽然他们都会被init进程收养,但是他们是不一样的进程。
守护进程会随着系统的启动默默地在后台运行,周期地完成某些任务或者等待某个事件的发生,直到系统关闭守护进程才会结束。
孤儿进程则不是,孤儿进程会因为完成使命后结束运行。

僵死进程:一 个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程. 但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程, 因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程, 看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init 来接管他,成为他的父进程……


阅读(1272) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~