繁体   English   中英

如果父进程退出,我如何防止子进程不成为僵尸

[英]How can i prevent a child process to NOT become a zombie if parent exits

我的主要过程产生了一个子进程。 如果主要进程被杀死,则子进程将被赋予ppid 1.当子进入时,它将变为僵尸,因为init没有对此子进行wait()调用。 有没有办法避免这种情况?

init 在它继承的进程上调用wait() 僵尸应该只存在于孩子已经离开的地方但是父母还在,但还没有获得退出代码。 init页:

init是系统上所有进程的父进程,它由内核执行,负责启动所有其他进程; 它是所有过程的父母,其天然父母已经死亡, 并且有责任在他们死亡时收获这些过程。

你应该让孤儿之间的区别(但他们仍然活着,他们的父母已经死了,因此他们已经通过init )和僵尸(他们死了,但他们的父母还活着,还没有收获它们)。

孤儿在退出后会在很短的时间内成为僵尸,但在init收获之前,但是这个时期应该足够小,没有人注意到。 事实上, 所有现有的进程(除了可能是init本身)都经历了这个短暂的僵尸阶段,只有那些父母没有足够快收获你注意到的情况。


init child death( SIGCHLD )处理程序中的实际代码是这样的(我的评论):

void chld_handler (int sig) {
    CHILD  *ch;
    int    pid, st;
    int    saved_errno = errno;

    while ((pid = waitpid(-1, &st, WNOHANG)) != 0) { // << WAIT done here
        if (errno == ECHILD) break;
        for (ch = family; ch; ch = ch->next) {
            if (ch->pid == pid && (ch->flags & RUNNING)) {
                INITDBG (L_VB, child_handler: marked %d as zombie", ch->pid);
                ADDSET (got_signals, SIGCHLD);
                ch->exstat = st;
                ch->flags |= ZOMBIE;                 // Set to zombie here.
                if (ch->new) {
                    ch->new->exstat = st;
                    ch->new->flags |= ZOMBIE;
                }
                break;
            }
        }
        if (ch == NULL) {
            INITDBG (L_VB, "chld_handler: unknown child %d exited.", pid);
        }
    }
    errno = saved_errno;
}

然后,稍后在主循环(不是信号处理程序)中,清除标记为ZOMBIE的进程表中的任何进程:

if (ISMEMBER (got_signals, SIGCHLD)) {
    INITDBG(L_VB, "got SIGCHLD");
    /* First set flag to 0 */
    DELSET(got_signals, SIGCHLD);

    /* See which child this was */
    for (ch = family; ch; ch = ch->next) {
        if (ch->flags & ZOMBIE) {                    // ZOMBIE detected here
            INITDBG (L_VB, "Child died, PID= %d", ch->pid);
            ch->flags &= ~(RUNNING|ZOMBIE|WAITING);  // And cleared here.
            if (ch->process[0] != '+') {
                write_utmp_wtmp ("", ch->id, ch->pid, DEAD_PROCESS, NULL);
            }
        }
    }
}

在程序的最后放置一个等待(NULL)语句,以便父和子等待彼此,直到它们都完成执行并且从任何人都不成为僵尸进程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM