在平台上做进程管理,之前一直以为需要是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