Python守护程序:检查是否始终运行一个守护程序

时间:2014-09-30 14:18:05

标签: python daemon python-daemon

myalert.py

from daemon import Daemon
import os, time, sys

class alertDaemon(Daemon):
    def run(self):
        while True:
            time.sleep(1)

if __name__ == "__main__":
    alert_pid = '/tmp/ex.pid'

    # if pid doesnt exists run
    if os.path.isfile(alert_pid):            # is this check enough?
        sys.exit(0)

    daemon = alertDaemon(alert_pid)
    daemon.start()

鉴于没有其他程序或用户会创建pid文件:

1)是否存在pid不存在但守护进程仍在运行的情况? 2)是否存在pid确实存在且守护程序没有运行的情况?

因为如果对上述问题中的至少一个问题的回答是肯定的,那么如果我的目标是一直运行一个守护进程,那么仅仅检查pid文件的存在是不够的。

问:如果我必须检查过程,那么我希望避免像系统调用ps -ef和grep这样的脚本名称。有没有一种标准的方法呢?

注意:脚本myalert.py将是一个cronjob

2 个答案:

答案 0 :(得分:2)

python-daemon库,它是PEP 3143的参考实现:“标准守护程序进程库”,通过在pid上使用文件锁(通过lockfile库)来处理文件传递给DaemonContext对象。底层操作系统保证在守护程序进程退出时将释放文件锁,即使它已被不正确地退出。这是一个简单的用法示例:

import daemon
from daemon.pidfile import PIDLockFile

context = daemon.DaemonContext(
    pidfile= PIDLockFile('/var/run/spam.pid'),
    )

with context:
    main()

因此,如果新实例启动,则不必确定创建现有pid文件的进程是否仍在通过pid本身运行;如果它可以获取文件锁,则没有其他实例正在运行(因为它们已经获得了锁)。如果它无法获取锁,则必须运行另一个守护进程实例。

遇到麻烦的唯一方法是,如果有人出现并在守护程序运行时手动删除了pid文件。但我认为你不必担心某人故意以这种方式破坏事物。

理想情况下,python-daemon将成为标准库的一部分,就像PEP 3143的最初目标一样。不幸的是,PEP被推迟了,主要是因为没有人愿意真正做剩余的工作需要得到添加到标准库中:

  

进一步探讨本PEP所涵盖的概念   因缺乏有兴趣推广的现任冠军而推迟   PEP的目标,收集和整合反馈,以及   足够的时间有效地做到这一点。

答案 1 :(得分:0)

我看到这种方式实施的几种方式:

  1. 检查是否存在pid文件 - >如果是这样,请退出并显示错误消息,例如" pid文件存在 - 如果您确定没有进程正在运行,请退出"

  2. 检查pidfile是否存在 - >如果是,请检查是否存在具有该pid的进程 - >如果是这样,就告诉用户"进程正在运行.."。冲突的风险(重复用于另一个进程)PID数量非常小,以至于它被忽略了;告诉用户如果发生错误,如何重新启动程序

  3. 提示:检查进程是否存在,您可以检查/proc/<pid>目录

    还要确保在脚本退出时尽可能删除pid文件,例如:

    1. 将代码换成try .. finally

      # Check & create pidfile
      try:
          # your application logic
      
      finally:
          # remove pidfile
      
    2. 您甚至可以安装信号处理程序(通过signal模块),在收到通常不会引发异常的信号时删除pidfile,而是直接退出。