Пишу демон на питоне, необходимо чтобы он не давал запустить копию себя, если он уже работает. При этом, нужно чтобы он правильно обрабатывал ситуацию, когда он был экстренно завершен.
Для демонизации использую python-daemon из PEP-3143. В общем случае, демон выглядит так:
# -*- coding: utf-8 -*-
import os
import daemon
import time
PIDFILE='/tmp/foo.pid'
class App():
def __init__(self):
self.stdin_path = '/dev/null'
self.stdout_path = '/dev/tty'
self.stderr_path = '/dev/tty'
self.pidfile_path = PIDFILE
self.pidfile_timeout = 5
def run(self):
while True:
print "test..."
time.sleep(10)
app = App()
daemon_runner = runner.DaemonRunner(app)
daemon_runner.do_action()
Но, несмотря на pid-файл второй демон запускается спокойно.
Самое простое что пришло в голову - проверять os.path.exists(PIDFILE)
, а потом try os.kill(pidfile.read_pid(), 0)
и ловить except OSError
Но, выглядит как-то костылевато.
Когда гуглил, нашел функцию http://www.thecodingforums.com/threads/single-instance-daemons.644188/
def single_instance(id):
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
sock.bind('\0' + id)
return sock
Но, ума не приложу как ей пользоваться, она у меня валится на sock.bind
Еще я нашел такую проверку (средствами самого python-daemon):
pidfile = daemon.pidfile.TimeoutPIDLockFile("/tmp/mydaemon.pid", -1)
if daemon.runner.is_pidfile_stale(pidfile):
Как правильно ограничивать количество копий процесса? Можете просто ткнуть в доки или бросить ссылкой.