c - 在设置子收割机时,是否有一些关于如何使用 prctl() 的简短示例?
问题描述
我目前正在尝试学习如何使用 Linuxprctl(PR_SET_CHILD_SUBREAPER)
和prctl(PR_GET_CHILD_SUBREAPER)
.
不幸的是,当我使用这些功能时,我似乎不明白发生了什么。有人可以帮助我发现我的理解上的失误吗?
我已将主进程设置为子收割机。然后我尝试使用fork()
创建一个子进程并再次执行以获得一个孙子进程。然后我杀死了子进程,看看孙子发生了什么,但我无法检查它。
int main(void) {
int p = fork();
prctl(PR_SET_CHILD_SUBREAPER, 1);
if(p < 0)
return EXIT_FAILURE;
if(p > 0){
//Main process
printf("I am the MainProcess, My PID: %d and PPID: %d\n", getpid(), getppid());
}
else{
printf("I am the Child, My PID: %d and PPID: %d\n", getpid(), getppid());
int p2 = fork();
if(p2 < 0)
return EXIT_FAILURE;
if(p2 > 0){
//still Child process
}
else{
int *reaper = NULL;
prctl(PR_GET_CHILD_SUBREAPER, reaper);
printf("I am the Grandchild, My PID: %d and PPID: %d\n", getpid(), getppid());
printf("Reaper ID: %d\n", *reaper);
kill(getppid(), SIGKILL);
printf("I am the Grandchild, My PID: %d and PPID: %d\n", getpid(), getppid());
prctl(PR_GET_CHILD_SUBREAPER, reaper);
printf("Reaper ID: %d\n", *reaper);
}
return EXIT_SUCCESS;
}
return EXIT_SUCCESS;
}
输出:
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
令我惊讶的是,一些printf()
事件(在代码的孙子部分)没有在运行时调用。原因是什么?
解决方案
这是一个 PR_SET_CHILD_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;
}
输出:
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
观察:
通过设置 PR_SET_CHILD_SUBREAPER,父进程(4002)已成为子收割者
PARENT 进程(4002)已分叉并创建了 CHILD 进程(4003)
CHILD 进程(4003)已分叉并创建了孙进程(4004)
CHILD 进程 (4003) 尝试使用 PR_GET_CHILD_SUBREAPER 并收到 0。由于 prctl() 只有实例,它不会保留在分叉的进程中。CHILD_SUBREAPER 位是否在 fork() 中持续存在?
CHILD 进程 (4003) 终止使 Grandchild 进程 (4004) 成为孤儿进程
由于,父进程(4002)已设置为 SUBREAPER 孙进程(4004)成为父进程(4002)的子进程,并且父进程(4002)收到孙进程(4004)的退出状态,因为子进程已终止
推荐阅读
- python - 检查模型的量化状态
- javascript - 在 div 悬停时,在第三个 div 上显示一个新 div
- mysql - 如何从 SQL 中的短语中匹配一个关键字
- codeigniter - 默认 URL 在 Codeigniter 中不起作用
- html - React:在样式组件中输入标签
- angular - Angular i18n nginx 重定向
- node.js - 在 Bot Framework v4 中为来自 msteams 的个人范围获取会话更新的 context.activity 中的 membersRemoved
- c# - .NET Core HealthCheck - 使用依赖注入和参数添加 HealthCheck
- swift - 使用 iOS SDK 发布到 FB 页面失败,而 Graph API Explorer 工作
- react-native - 操作“firebase_app_distribution”不可用,运行“fastlane 操作”以获取完整列表