【发布时间】:2014-08-30 23:44:36
【问题描述】:
在运行守护程序时,一个常见的 Linux/UNIX 习惯用法是生成守护程序,并创建一个仅包含守护程序进程 ID 的 PID 文件。这样,要停止/重新启动守护程序,您只需拥有 kill $(cat mydaemon.pid)
现在,这里有很多机会出现不一致的状态。假设运行守护程序的机器被强制关闭,然后重新启动。现在你有一个 PID 文件,它引用了一个不存在的进程。
好的,所以没问题...您的守护进程将尝试杀死不存在的进程,发现它不是真正的进程,然后照常继续。
但是...如果它是一个真正的进程——只是不是你的守护进程怎么办?如果是别人的流程,或者其他重要的流程怎么办?你无法知道——所以杀死它是有潜在危险的。一种可能性是检查进程的名称。当然,这也不是万无一失的,因为没有理由另一个进程可能没有相同的名称。特别是,例如,如果您的守护进程在解释器(如 Python)下运行,在这种情况下,进程名称永远不会是唯一的 - 它只是“python”,在这种情况下,您可能会无意中杀死其他人的进程。
那么我们如何处理这种需要重启守护进程的情况呢?怎么知道pid文件中的PID一定是daemon?
【问题讨论】:
-
通常你会向它发送一个 SIGTERM,它与
kill相同,我相信没有任何标志 -
您从哪个角度提出问题:从想要管理守护进程的系统程序员的角度来看,或者从想要提供脚本的守护进程开发人员的角度来看用户启动/停止她自己的守护进程?
-
这是一个有趣的问题...我是从守护程序开发人员的角度思考问题的,但我不明白为什么这很重要。
-
守护进程管理器(例如 systemd)通常一直运行并且是 PID 1。因此它完全了解所有守护进程(因为它们是 PID 1 的直接子进程,因为它们已经分叉并且分离),这使它处于稍微不同的位置。
-
现实情况是,根本不存在向非子进程发送信号的无竞争方式。如果你觉得你绝对需要一种方法来杀死一个无竞争的管理器中的守护进程,你应该以不同的方式管理你的守护进程。 (通过 Unix 套接字通信关闭,使用 systemd 或其他 init 守护进程,或创建您自己的管理进程来生成和终止守护进程。)