【问题标题】:Linux /proc/PID dir of child stays alive after parent kills child父母杀死孩子后,孩子的Linux /proc/PID dir仍然活着
【发布时间】:2014-08-19 11:08:34
【问题描述】:

似乎如果我创建一个进程,将其分叉并从父级向子级发送 SIGHUP,则子级会死掉,但它的“/proc/PID”目录不会消失,直到父级也死了。 (见下面的代码)。

让父母检查孩子是否死了的正确方法是什么?

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
#include <signal.h>

void testprocdir(pid_t pid) {
    struct stat sb;
    char path[1024];

    sprintf(path,"/proc/%d",pid);
    if(stat(path, &sb)==-1 && errno == ENOENT) {
            printf("%s does not exist\n", path);
    } else {
            printf("%s exists\n", path);
    }
}

int main(int argc,char **argv) {
    pid_t parent,child;

    parent=getpid();
    printf("I am %d\n",parent);
    child=fork();
    switch(child) {
    case -1:
            printf("Forking failed\n");
            return 2;
    case 0: 
            parent=getppid();
            child=getpid();
            printf("I am the child (%d) and my parent is %d\n", child, parent);
            while(1) { sleep(1); printf("I am the child and I have slept 1s\n");}
            printf("This line should not be visible\n");
    }
    sleep(1); //make sure kid is in the while loop
    printf("I am the parent (%d) and my kid is %d\n", parent, child);
    kill(child,SIGHUP);
    testprocdir(parent);
    printf("Waiting 5s before testing if the procdir of the child (/proc/%d) is removed\n",child);
    sleep(5);
    testprocdir(child);
    return 0;
}

【问题讨论】:

    标签: c linux fork pid procfs


    【解决方案1】:

    您可以使用wait 系列系统调用。

    【讨论】:

    • 值得注意的是,尽管它们的名字,等待函数不一定“等待”。使用 WNOHANG 标志,可以使 waitpid() 变为非阻塞,满足 OP 检查孩子是否死亡的原始请求。
    【解决方案2】:

    fork在父进程中返回子进程的PID,在子进程中返回0。

    man waitpid 应该提供足够多的指示,以便在父进程中调用 waitpid,允许您检查该子进程或所有子进程 - 包括允许父进程在子进程仍然执行时继续执行的能力活着或停止父级中的所有执行,直到子级死亡。

    【讨论】:

      【解决方案3】:

      我将从一些概念开始:

      操作系统将在进程表中保留子进程的条目(包括退出状态),直到父进程调用 waitpid(或另一个等待系列函数)或直到父进程退出(此时状态由初始化进程)。这就是“僵尸”进程:已经退出的进程仍然驻留在进程表中,正是为了这个目的。在第一次调用 waitpid 后,表中的进程条目应该消失。

      另外,从手册页:

      终止但没有被等待的孩子变成了“僵尸”。内核维护了有关僵尸进程的一组最小信息(PID、终止状态、资源使用信息),以便让父进程稍后执行等待以获取有关子进程的信息。

      因此,通过使用 wait 系列函数,您可以检查子进程的状态。 还有一些宏可以与 wait 系列函数一起使用来检查子进程的状态,如 WEXITSTATUS、WIFSIGNALED、WIFEXITED 等。

      【讨论】:

        猜你喜欢
        • 2012-01-03
        • 2020-08-07
        • 2016-11-09
        • 1970-01-01
        • 2012-01-21
        • 1970-01-01
        • 2014-12-14
        • 1970-01-01
        • 2019-01-18
        相关资源
        最近更新 更多