所以在C和C ++中,我一直在使用prctl(PR_SET_PDEATHSIG,SIGKILL); 而且效果很好。当我在shell脚本中生成子进程时,我会使用如下代码:
pid=$!
trap "kill $pid" SIGHUP SIGINT SIGTERM
wait
Run Code Online (Sandbox Code Playgroud)
这在所有情况下工作,除了当shell脚本得到一个SIGKILL(它不能赶上)。然后,我最终得到了外壳脚本的子级为僵尸。
Shell脚本是否可以将SIGKILL传递给其子级?我对适用于哪种外壳很开放,但理想情况下是bash或sh。
因此,基于下面的评论,我将提供一些背景知识,看看我是否应该完全使用其他方法。我们的设置大致遵循以下原则:
+ systemd
+ a_c_process
+ a_c_process
+ a_c_process
+ a_leaf_c_process
+ shellscriptA
+ a_leaf_c_process
+ a_leaf_c_process
Run Code Online (Sandbox Code Playgroud)
因此,尽管SIGTERM可以作为我们的开始信号(例如,任何非叶子c进程都可以在收到SIGTERM时将SIGTERM发送给它的所有子进程),但是如果树中的进程不能正确处理SIGTERM,我的理解是我应该期望系统化提供一个SIGKILL。我们一直在使用PR_SET_PDEATHSIG来确保清除整个进程树中的僵尸。
从我可以看到的角度来看,该技术应该能够与SIGTERM处理并存。也就是说,我可以安装SIGTERM处理程序,但是如果这些处理程序失败,也可以使用PR_SET_DEATHSIG作为后备。
您所描述的是孤儿进程。
\n\n如果 shell 脚本是监督者,并且 shell 脚本本身被杀死,它将无法再监督它的子脚本。
\n\n这些进程现在变成了孤儿进程,责任落在 PID 1(操作系统的 init 程序)上。(这就是具有多个进程的 Docker 容器受益于使用init 进程启动的原因。Bash 不擅长处理这项工作。)
\n\n我本来打算建议您使用 systemd,所以幸运的是您已经在使用它了。\n这里有一篇相关的博客文章:http://0pointer.de/blog/projects/systemd-for-admins-4 .html
\n\n据我所知,systemd 处理孤儿。我做了一个小实验来证实:
\n\n# echo \'#!/bin/sh\n\ntail -f /dev/null &\ntail -f /dev/null &\ntail -f /dev/null &\n\nwait\' > /usr/local/bin/orphan\n# chmod +x /usr/local/bin/orphan\n# echo \'[Unit]\nDescription=Orphan process experiment\n\n[Service]\nType=simple\nExecStart=/usr/local/bin/orphan\' > /etc/systemd/system/orphan.service\n# systemctl start orphan.service\n# systemctl status orphan.service\n\xe2\x97\x8f orphan.service - Orphan process experiment\n Loaded: loaded (/etc/systemd/system/orphan.service; static; vendor preset: disabled)\n Active: active (running) since Wed 2020-02-12 17:51:07 UTC; 1s ago\n Main PID: 226742 (orphan)\n Tasks: 4 (limit: 38298)\n Memory: 1.1M\n CGroup: /system.slice/orphan.service\n \xe2\x94\x9c\xe2\x94\x80226742 /bin/sh /usr/local/bin/orphan\n \xe2\x94\x9c\xe2\x94\x80226744 tail -f /dev/null\n \xe2\x94\x9c\xe2\x94\x80226745 tail -f /dev/null\n \xe2\x94\x94\xe2\x94\x80226746 tail -f /dev/null\n\nFeb 12 17:51:07 localhost systemd[1]: Started Orphan process experiment.\n# kill -9 226742\n# systemctl status orphan.service\n\xe2\x97\x8f orphan.service - Orphan process experiment\n Loaded: loaded (/etc/systemd/system/orphan.service; static; vendor preset: disabled)\n Active: failed (Result: signal) since Wed 2020-02-12 17:52:51 UTC; 9s ago\n Process: 226742 ExecStart=/usr/local/bin/orphan (code=killed, signal=KILL)\n Main PID: 226742 (code=killed, signal=KILL)\n\nFeb 12 17:51:07 localhost systemd[1]: Started Orphan process experiment.\nFeb 12 17:52:51 localhost systemd[1]: orphan.service: Main process exited, code=killed, status=9/K>\nFeb 12 17:52:51 localhost systemd[1]: orphan.service: Failed with result \'signal\'.\n# ps aux | grep tail\nroot 227721 0.0 0.0 6288 2196 pts/3 S+ 17:54 0:00 grep --color=auto tail\nRun Code Online (Sandbox Code Playgroud)\n\n成功。systemd 清理了孤儿。
\n\n我不知道systemd 是通过cgroup还是subreaper来实现这一点。我猜是前者。
\n\n看来这位疯狂的科学家已经在 Go 中实现了 subreaper:https://medium.com/@william.la.martin/dont-fear-the-subreaper-19c8127c031e。如果你感觉特别邪恶,这可能是一条可以走的路。
\n\n最后一点,孤儿和相关概念的整个磨难是我喜欢 systemd-logind\ 的KillUserProcesses=yes的原因。它让我确信,无论我登录时软件在做什么,延迟的进程都会在注销时被清理。内心的平静。
\n| 归档时间: |
|
| 查看次数: |
299 次 |
| 最近记录: |