Unix进程关系—僵死进程与孤儿进程

来源:互联网 发布:嵌入式软件分层设计 编辑:程序博客网 时间:2024/05/21 07:47

       如果父进程在子进程之前终止,子进程先成为孤儿进程,此后子进程的父进程变为init进程。我们称这些进程由init进程领养。其操作过程大致是:在一个进程终止时,内核逐个检查所有活动进程,以判断它是否是正要终止的进程的子进程,如果是,则该进程的父进程ID就更改为1(init进程的ID)。这种处理方法保证了每个进程有一个父进程。

       如果子进程在父进程之前终止,那么父进程又如何能在做相应检查时得到子进程的终止状态呢?内核为每个终止子进程保存了一定量的信息,当终止进程的父进程调用wait或waitpid 时,可以得到有关信息。这种信息至少包括进程I D、该进程的终止状态、以反该进程使用的CPU时间总量。内核可以释放终止进程所使用的所有存储器,关闭其所有打开文件。在UNIX中,一个已经终止、但是其父进程尚未对其进行善后处理(获取终止子进程的有关信息、释放它仍占用的资源)的进程被称为僵死进程。如果编写一个长期运行的程序,它fork了很多子进程,那么除非父进程等待取得子进程的终止状态,否则这些子进程就会变成僵死进程。


实例代码(孤儿进程):

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
       pid_t pid;
       pid = fork();

       if(pid == 0)
       {
             printf("before father end\n");
             printf("my process id is %d, my father is %d\n", getpid(), getppid());
             sleep(10);
             printf("after father end\n");
             printf("my process id is %d, my father is %d\n", getpid(), getppid());
       }
       else if(pid > 0)
       {
             sleep(5);
       }
       else
       {
             printf("error");
       }
       return 0;
}

代码分析:

      程序中,子进程挂起10秒,父进程挂起5秒,以保证父进程先于子进程结束。


运行结果:


结果分析:

      这里可能会感到奇怪,不是说应该是由进程ID为1的init进程来接管孤儿进程吗?这是因为实验环境的关系,在我的实验环境Ubuntu中,系统使用进程upstart代替init来接管了孤儿进程。我们可以通过ps axu|grep 1364来查看指定进程ID的具体信息,如下:


实例代码(僵死进程):

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
       pid_t pid;
       pid = fork();

       if(pid == 0)
       {
             sleep(5);
       }
       else if(pid > 0)
       {
             sleep(10);
       }
       else
       {
             printf("error");
       }
       return 0;
}

代码分析:

      程序中,子进程挂起5秒,父进程挂起10秒,以保证子进程先于父进程结束。


运行结果(状态为Z+的即表示僵死进程):



0 0
原创粉丝点击