在平台上做进程管理,之前一直以为需要是init进程,因为orphane进程的父进程会变成1号进程。但是今天在我的fedora上,在后台执行一个gedit进程,然后shell退出,发现gedit的父进程竟然是systemd。于是搜索了一下,发现Linux有一个child sub reaper机制。
进程可以通过prctl系统调用,设置其为sub reaper。这样其子孙进程变成孤儿进程时,就会寻找一个最近的sub reaper祖先,作为其父进程。
一个简单的程序,证明sub reaper
#include <linux/prctl.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
int ret;
int pid;
ret = prctl(PR_SET_CHILD_SUBREAPER, 1);
if (ret < 0) {
fprintf(stderr, "PR_SET_CHILD_SUBREAPER failed: %m\n");
return 1;
}
printf("sub reaper pid %d\n", getpid());
pid = fork();
if (pid == 0) {
printf("child %d\n", getpid());
pid = fork();
if (pid == 0) {
printf("child of child %d\n", getpid());
sleep(1);
printf("ppid %d\n", getppid());
}
}
else if (pid > 0) {
while (1) {
ret = wait(NULL);
if (ret < 0)
break;
printf("wait pid %d\n", ret);
}
}
return 0;
}$ ./a.out
sub reaper pid 9785
child 9786
child of child 9787
wait pid 9786
ppid 9785
wait pid 9787
fork两次,子进程退出,孙子进程变成孤儿进程,打印ppid。可以发现,其ppid为主进程。
参考:
https://blog.csdn.net/ACMer_L/article/details/108168694
https://unix.stackexchange.com/questions/250153/what-is-a-subreaper-process
https://www.man7.org/linux/man-pages//man2/PR_SET_CHILD_SUBREAPER.2const.html