是否有一些简短的示例说明如何在设置Subreaper时使用prctl()?

是否有一些简短的示例说明如何在设置Subreaper时使用prctl()?,c,linux,process,C,Linux,Process,我目前正在尝试学习如何使用Linuxprctl(PR\u SET\u CHILD\u SUBREAPER),以及prctl(PR\u GET\u CHILD\u SUBREAPER) 不幸的是,当我使用这些函数时,我似乎不明白发生了什么。有人能帮我找出我理解上的错误吗 我已将主进程设置为subreaper。然后,我尝试使用fork()创建一个子进程,并再次尝试以获得一个孙进程。然后我杀了child进程,看看孙子发生了什么,但我无法检查 int main(无效){ int p=fork(); pr

我目前正在尝试学习如何使用Linux
prctl(PR\u SET\u CHILD\u SUBREAPER)
,以及
prctl(PR\u GET\u CHILD\u SUBREAPER)

不幸的是,当我使用这些函数时,我似乎不明白发生了什么。有人能帮我找出我理解上的错误吗

我已将主进程设置为subreaper。然后,我尝试使用
fork()
创建一个子进程,并再次尝试以获得一个孙进程。然后我杀了child进程,看看孙子发生了什么,但我无法检查

int main(无效){
int p=fork();
prctl(PR_SET_CHILD_SUBREAPER,1);
if(p<0)
返回退出失败;
如果(p>0){
//主要过程
printf(“我是主进程,我的PID:%d和PPID:%d\n”,getpid(),getppid());
}
否则{
printf(“我是孩子,我的PID:%d和PPID:%d\n”,getpid(),getppid());
int p2=fork();
if(p2<0)
返回退出失败;
如果(p2>0){
//静子过程
}
否则{
int*reaper=NULL;
prctl(PR_GET_CHILD_SUBREAPER,收割器);
printf(“我是孙子,我的PID:%d和PPID:%d\n”,getpid(),getppid());
printf(“收割者ID:%d\n”,*收割者);
kill(getppid(),SIGKILL);
printf(“我是孙子,我的PID:%d和PPID:%d\n”,getpid(),getppid());
prctl(PR_GET_CHILD_SUBREAPER,收割器);
printf(“收割者ID:%d\n”,*收割者);
}
返回退出成功;
}
返回退出成功;
}
输出:

I am the MainProcess, My PID: 9088 and PPID: 23010
I am the Child, My PID: 9089 and PPID: 9088
I am the Grandchild, My PID: 9090 and PPID: 9089
PARENT:Set: Success
PARENT: 4002 :  my dad : 2222
Before CHILD: 4003: my dad  4002
After CHILD : 0
After CHILD: 4003: my dad  4002
CHILD Exiting
Before grandchild: 4004: my dad 4003
After grandchild: 4004: my dad 4002
After grandchild : 0
Grandchild Exiting
PARENT : 1
PARENT Exiting

令我惊讶的是,一些
printf()
实例(在代码的granchild部分)在运行时没有被调用。原因是什么?

这里有一个关于PR\u SET\u CHILD\u SUBREAPER如何工作的小程序

#include <stdio.h>
#include <sys/types.h>
#include <sys/prctl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>

int main(void)
{
    int *status;
    int i=0;

    prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0);
    perror("PARENT:Set");
    printf("PARENT: %d :  my dad : %d\n", getpid(), getppid());
    if(fork() != 0)
    {
        while(1)
        {
            wait(status);
            if(++i == 2)
            {
                break;
            }
        }
        int p = 1;
        prctl(PR_GET_CHILD_SUBREAPER, &p);
        printf("PARENT : %d\n",p);
        printf("PARENT Exiting\n");
    }
    else
    {
        printf("Before CHILD: %d: my dad  %d\n",getpid(), getppid());
        if(fork() == 0)
        {
            int p = 1;
            printf("Before grandchild: %d: my dad %d\n",getpid(), getppid());
            sleep(2);
            printf("After grandchild: %d: my dad %d\n",getpid(), getppid());
            prctl(PR_GET_CHILD_SUBREAPER, &p);
            printf("After grandchild : %d\n",p);
            printf("Grandchild Exiting\n");
            exit(0);
        }
        else
        {
            int p = 1;
            prctl(PR_GET_CHILD_SUBREAPER, &p);
            printf("After CHILD : %d\n",p);
            printf("After CHILD: %d: my dad  %d\n",getpid(), getppid());
            printf("CHILD Exiting\n");
            exit(1);
        }
    }   
    return 0;
}
观察:

通过设置PR_SET_CHILD_SUBREAPER,父进程(4002)已成为子进程

父进程(4002)已分叉并创建子进程(4003)

子进程(4003)派生并创建了孙进程(4004)

子进程(4003)尝试使用PR_GET_CHILD_SUBREAPER并接收0。因为,prctl()只有一个实例,它不会保留在分叉进程中

子进程(4003)终止使孙子进程(4004)成为孤立进程


因为,父进程(4002)被设置为子收割机孙进程(4004)成为父进程(4002)的子进程,并且父进程(4002)接收到孙进程(4004)的退出状态,因为子进程已终止

这可能是有用的信息: