**Linux 知识补充 -- 守护进程的编写及使用方法 - 04 如何杀死守护进程及其子进程** 1652270 **冯舜** ## 写 `test4-1.c` 编辑 `test4-1.c` 的内容: ~~~~~~~~~~~~~C ~~~~~~~~~~~~~ 编译运行之, 其输出的前几行如下: !![4pids,`test4-1` 的输出] ## 杀死 `test4-1` 分裂出的一个子进程 使用 `ps -f f -C test4-1` 查看进程树, 然后使用 `kill PID号` 杀死其中一个子进程即可. !![4kill,用 PID 杀死子进程] ## 杀死 `test4-1` 分裂出的所有子进程 需要借助工具 `pkill`. 记录下 `test4-1` 进程的 PID, 用 `pkill -P 父进程PID` 可以杀死所有子进程. !![4pkill,用 `pkill` 杀死所有子进程] ## 当杀死父进程时, 子进程的变化 使用 `kill 父进程PID` 杀死父进程. 用 `ps -f f -C test4-1` 查看其余进程, 发现它们的父进程 PID 变为 1, 说明作为孤儿进程被 `init`(systemd) 接纳. 同时, 它们的 `STAT` 也去除了 `+` 属性, 说明它们不再是原控制台(会话)的前台进程. !![4killparent,杀死父进程后子进程的变化] ## 改进 `test4-1`, 使之被杀死时杀死所有子进程 ### 方法 1 : 父进程捕获终止信号 需要在 `test4-1` 的基础上, 使程序捕获 `SIGTERM` 等终止信号, 并在其处理函数中用 `kill(0, SIGTERM)` 终止所有同组进程. 编辑 `test4-2.c` 的内容: ~~~~~~~~~~~~~C ~~~~~~~~~~~~~ 编译运行它, 杀死父进程再查看进程信息, 发现子进程也随之消失. !![4killparent2,子进程随父进程消失] 但是由于 `SIGKILL` 信号是无法捕获的, 所以这个方法对于 `SIGKILL` 方式杀死父进程的情况无效. !![4kill9,`-9` 方式杀进程, 该方法无效] ### 方法 2 : 子进程使用 `prctl` 要求系统终止 另一个实现它的方法是通过在子进程中调用 `prctl(PR_SET_PDEATHSIG, SIGTERM)` (见 `test4-2_prctl.c`) 使系统在父进程死亡时, 向所有子进程发送 `SIGTERM` 以终止它们. 这个方法可以正确处理 `SIGKILL` 杀死父进程的情况. 不过, 这个函数只在 Linux 下起作用, 不符合 POSIX 标准. !![4prctl,`-9` 方式杀进程, 可以使用 `prctl` 方法正确处理]