守护程序 X 生成进程 Y 。有时守护进程 X 可能会突然死亡,在这种情况下,它没有机会正确终止其子进程 Y (即进程 Y 将继续在后台运行)。 如果 X 突然死亡,如何确保 Y 始终终止?
目前我已经实现了守护程序 X ,如果它突然死亡,那么它会重新启动;读取流程' Y pid文件,并使用kill(pid, SIGTERM)
终止 Y 。然而,这个解决方案有它的缺点 - 在杀死进程 Y 之前,我需要确保它确实是进程 Y (因为其他一些新进程可以重用它在 Y 的pid文件中的pid)。即使如果 X 检查处理' Y 名称对/proc/<pid>/
,那么仍有一个小窗口理论上 X 可能会被杀死错误的过程。
由于我没有开发 Y 过程,我无法使用 Y 中的prctl(PR_SET_PDEATHSIG, SIGTERM)
。
此外,system("killall Y")
对我的用例来说过于宽泛。
有没有比现在更好的方法解决这个问题?
答案 0 :(得分:4)
流程组/会话可能是最佳选择。怎么样:
如果 X 执行setsid()
,请将其从代码中删除。编写一个非常简单的包装器shell脚本来运行守护程序:
#!/bin/sh
/usr/bin/xd || pkill -TERM -s 0
并使用setsid
命令运行它。如果守护进程异常退出,pkill
将向当前会话中的所有进程发送致命信号。会话通过fork()
/ exec()
继承,会话负责人(shell进程)在执行pkill
时仍然存在,因此除非子进程setsid()
,否则孩子没有机会逃脱或杀死错误的过程。
答案 1 :(得分:0)
对于Linux 仅:
使用带有选项PR_SET_PDEATHSIG
的函数prctl()
允许 parent 子项设置一个信号,发送给他们的孩子以防万一父母去世了。仅适用于设置此选项后创建的子项。
从ptctl()
的Linux手册页中逐字逐句:
PR_SET_PDEATHSIG (自Linux 2.1.57起)
将调用进程的父进程死亡信号设置为 arg2(信号值在1..maxsig范围内,或0到 明确)。这是调用进程将获得的信号 当它的父母去世时为孩子清除此值 fork(2)和(自Linux 2.4.36 / 2.6.23)执行时 set-user-ID或set-group-ID binary。