[ related information ] * prctl * See linux kerne for details ("kernel/exit.c : find_new_reaper()) ------ commit(kernel/git/torvalds/linux.git) ----- http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ebec18a6d3aa1e7d84aab16225e87fd25170ec2b author Lennart Poettering <lennart@poettering.net> 2012-03-23 22:01:54 (GMT) committer Linus Torvalds <torvalds@linux-foundation.org> 2012-03-23 23:58:32 (GMT) commit ebec18a6d3aa1e7d84aab16225e87fd25170ec2b (patch) ===================================================================== [ test code ] ------------- $ cat b.sh function echosleep2 { sleep 10 echo 'sleep2 end' } function echosleep { echosleep2& sleep 5 echo 'sleep end' } echo "hello: $BASHPID $$" echosleep& sleep 2 echo end ===================================================================== ===================================================================== [common] -------- PID PPID PGID SID CMD 3241 2573 3241 3241 init --user ... 4392 3241 3374 3374 gnome-terminal ... 9882 4392 9882 9882 bash ... ===================================================================== ===================================================================== [ < 2 seconds ] --------------- PID PPID PGID SID CMD 33513 9882 33513 9882 bash # ./b.sh (*a) 33514 33513 33513 9882 bash # ./b.sh:echosleep() (*b) 33515 33513 33513 9882 sleep 2 33516 33514 33513 9882 bash # ./b.sh:echosleep():echosleep2() (*c) 33517 33514 33513 9882 sleep 5 33518 33516 33513 9882 sleep 10 33519 15742 33519 15742 ps -e -o pid,ppid,pgid,sid,cmd ------------- (*a): Bash terminal executed 'b.sh' as new process group leader. All child/grandchild processes are executed in the same process group. ===================================================================== ===================================================================== [ < 5 seconds ] --------------- PID PPID PGID SID CMD 33514 3241 33513 9882 bash # ./b.sh:echosleep() (*b) 33516 33514 33513 9882 bash # ./b.sh:echosleep():echosleep2() (*c) 33517 33514 33513 9882 sleep 5 33518 33516 33513 9882 sleep 10 33520 15742 33520 15742 ps -e -o pid,ppid,pgid,sid,cmd ------------- (*b): Process group leader(*a) is disappeared. And there is no threads in this process. (If there is other threads in this process, it will become new reaper) So, it is re-parented to orphan-reaper("init --user"). ===================================================================== ===================================================================== [ < 10 seconds ] ---------------- PID PPID PGID SID CMD 33516 3241 33513 9882 bash # ./b.sh:echosleep():echosleep2() (*c) 33518 33516 33513 9882 sleep 10 33522 15742 33522 15742 ps -e -o pid,ppid,pgid,sid,cmd ------------- (*c): Same with above(*b). ===================================================================== ===================================================================== [ > 10 seconds ] ---------------- PID PPID PGID SID CMD 33524 15742 33524 15742 ps -e -o pid,ppid,pgid,sid,cmd ------------- ===================================================================== Sample code to get every SIGCHLD from descendents. --------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <string.h> #include <sys/wait.h> #include <sys/prctl.h> #include <errno.h> void handle_signal(int signal) { pid_t pid; printf("Handler SIGCHLD: %d\n", signal); if (0 > (pid = wait(NULL))) { printf("Wait fails: errno: %s", strerror(errno)); } else { printf("Wait done: %d\n", pid); } } int main() { struct sigaction sa; pid_t pid; // Print pid, so that we can send signals from other shells printf("My pid is: %d\n", getpid()); // Setup the sighub handler sa.sa_handler = &handle_signal; // Intercept SIGHUP and SIGINT if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("Error: cannot handle SIGCHLD"); // Should not happen } if (0 > prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0)) { perror("Error: prctl"); } pid = fork(); if (pid) { int secs = 10; // parent printf("\nSleeping for 10 second\n"); while (secs > 0) secs = sleep(10); printf("Parent DONE\n"); } else { // child if (0 > execlp("bash", "bash", "b.sh", NULL)) { printf("execl fails: %s\n", strerror(errno)); } } }
'Domain > Linux' 카테고리의 다른 글
[Ubuntu/Linux] Python zip library 와 7z 간 교차 사용시 문제 (0) | 2017.03.08 |
---|---|
Run commands with synchronization in shell. (0) | 2016.04.20 |
[Linux] Environment variable - more (0) | 2015.11.11 |
[Linux/Ext4] Order of file list of the directory in ext4 (1) | 2015.03.09 |
[Bash] signal을 받고 죽은 process의 exit code (0) | 2015.02.11 |