使用PID文件杀死守护程序

时间:2014-07-09 19:33:36

标签: linux unix daemon pid

运行守护进程时常见的Linux / UNIX习惯用法是生成守护进程,并创建一个PID文件,该文件只包含守护进程的进程ID。这样,要停止/重新启动守护程序,您只需拥有kill $(cat mydaemon.pid)

的脚本

现在,这里存在很多不一致状态的机会。假设强制关闭运行守护程序的计算机,然后重新启动。现在你有一个PID文件,它引用了一个不存在的进程。

好的,没问题......你的守护进程只会试图杀死不存在的进程,发现它不是一个真正的进程,并且像往常一样继续。

但是......如果它 是一个真正的过程 - 只是不是你的守护进程?如果是其他人的流程或其他重要流程怎么办?你无从知晓 - 所以杀死它是有潜在危险的。一种可能性是检查流程的名称。当然,这也不是万无一失的,因为没有理由另一个进程可能没有相同的名称。特别是,例如,如果您的守护进程在Python之类的解释器下运行,在这种情况下,进程名称永远不会是唯一的 - 它只是“python”,在这种情况下,您可能会无意中杀死其他人的进程。

那么我们如何处理这样的情况呢?我们需要重新启动一个守护进程?我们怎么知道pid文件中的PID必然是守护进程?

2 个答案:

答案 0 :(得分:0)

你只是继续添加偏执层:

  • pid文件
  • 进程名称匹配
  • 一些沟通渠道/金丝雀

为了确保pid在重启后不会过时,最重要的是将其存储在/var/run中,这是一个保证每次重启都会被清除的位置。 / p>

对于进程名称匹配,您实际上可以在fork / exec点重新定义进程的名称,这将允许您使用一些唯一的名称。

沟通渠道/金丝雀稍微复杂一些,容易出现问题。如果守护进程创建了一个命名套接字,那么套接字的存在+连接和与守护进程通信的能力将被视为进程正在运行的证据。

答案 1 :(得分:0)

如果你真的想为你的用户提供一个脚本,你可以让守护进程自己管理它的pid文件,并添加一个atexit和一个SIGABRT处理程序来取消链接pid文件,即使是不洁的关机。

更多方法还包括将进程启动时间存储在pidfile中。与易失性存储(例如/var/run)一起,这是识别进程的非常可靠的方法。这使得kill命令有点复杂。

但是,我个人认为守护程序开发人员不应该(太多)关心这一点,并让目标平台处理守护进程(systemd,upstart,good ol'SysV init脚本)。这些通常有更多的知识:例如,systemd会愉快地接受一个根本不会分叉的守护进程,允许它直接监视它的状态而不需要PID文件。然后,您可以为最常见的解决方案提供配置文件(目前可能是systemd,因为Debian也会迁移到它,因此它也会很快打到ubuntu),这通常比完全成熟的守护进程管理更容易编写。