如何在父进程重新启动时使子进程死亡

时间:2013-12-18 06:01:16

标签: c linux process daemon kill

守护程序 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")对我的用例来说过于宽泛。

有没有比现在更好的方法解决这个问题?

2 个答案:

答案 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。