【问题标题】:Single instance of a python daemon (with python-daemon)python 守护程序的单个实例(使用 python-daemon)
【发布时间】:2014-03-26 06:34:07
【问题描述】:

我想创建一个永远运行的程序,一次只运行一个实例,并且可以使用 init.d 脚本启动。 python-daemon 似乎是一个不错的选择,因为它是 PEP 3143 的参考实现。

无论如何,我无法理解 PID 锁定文件的用途,因为它不会阻止程序运行两次。

我是否应该手动检查 init.d 脚本中是否存在锁定文件(基于“/etc/init.d/skeleton”)?还有我应该怎么杀死它?获取 PID 文件中的 PID 号并发送 SIGTERM ?

非常感谢。

【问题讨论】:

  • 是什么让你这么说:“PID 锁定文件的用途,因为它不会阻止程序运行两次”。如果PID文件被锁定,取决于锁的实现,它可以阻止程序运行两次(第二个实例不会得到锁)。
  • 而且,是的,使用 PID 文件中的 PID 来杀死守护进程。
  • 我正在查看 htop 中的进程,两次启动后我看到了两个进程。其中一个正在睡觉,这不是我预期的行为。
  • 如果一个人正在睡觉,它可能正在等待锁定 - 实际上,进程已启动但未运行。

标签: python linux init.d python-daemon


【解决方案1】:

我最终使用了 Sander Marechal 的代码,该代码的站点当前已关闭,因此这里是 pastebin 的链接:http://pastebin.com/FWBUfry5

您可以在下面找到如何使用它的示例,它会产生我预期的行为:它不允许您启动两个实例。

    import sys, time
    from daemon import Daemon


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

    if __name__ == "__main__":
            daemon = MyDaemon('/tmp/daemon-example.pid')
            if len(sys.argv) == 2:
                    if 'start' == sys.argv[1]:
                            daemon.start()
                    elif 'stop' == sys.argv[1]:
                            daemon.stop()
                    elif 'restart' == sys.argv[1]:
                            daemon.restart()
                    else:
                            print "Unknown command"
                            sys.exit(2)
                    sys.exit(0)
            else:
                    print "usage: %s start|stop|restart" % sys.argv[0]
                    sys.exit(2)

【讨论】:

    【解决方案2】:

    对我来说,它通过 PID 文件有效地防止了第二个实例的启动。你使用正确吗?我的示例基于我在 the PEP 3143 reference 和来源中找到的内容:

    #!/usr/bin/env python
    
    import daemon, os, time, lockfile
    
    with daemon.DaemonContext(
        pidfile=lockfile.FileLock('./pydaemon.pid'),
        working_directory=os.getcwd()):
      for i in range(10):
        with open('./daemon.log', 'a') as logFile:
          logFile.write('%s %s\n' % (os.getpid(), i))
        time.sleep(1)
    

    如果我启动一次,它会创建 PID 锁定文件。如果我第二次启动它,第二个实例会休眠直到第一个实例完成;正常的守护进程不会完成,所以这有效地阻止了第二个实例。但是,如果第一个守护进程终止,则启动第二个。

    【讨论】:

      猜你喜欢
      • 2012-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-01
      • 1970-01-01
      相关资源
      最近更新 更多