当存在过时的PID文件时,python-daemon上下文启动失败

6 投票
2 回答
6631 浏览
提问于 2025-04-17 11:09

我在用python-daemon,遇到一个问题:当我用kill -9命令强制结束一个进程时,它会留下一个pid文件(这没问题),但下次我运行程序时,如果不手动删除这个pid文件,程序就无法正常工作(这就不太好了)。

我会捕获所有异常,以确保在程序终止之前调用context.close()。这样一来,当我用kill命令结束进程时,/var/run/mydaemon.pid*文件会被删除,之后再运行守护进程就能成功了。然而,当我使用SIGKILL(kill -9)时,我没机会调用context.close(),所以/var/run文件就留在那里。在这种情况下,下次我运行程序时,它就无法成功启动——原来的进程会返回,但守护进程在context.open()时会卡住。

看起来python-daemon应该能发现有一个已经不存在的进程的pid文件,并把它清除掉,但这并没有发生。我是不是应该手动去做这个?

注意:我不使用with,因为这段代码是在Python 2.4上运行的。

from daemon import DaemonContext
from daemon.pidlockfile import PIDLockFile

context = DaemonContext(pidfile = PIDLockFile("/var/run/mydaemon.pid"))
context.open()

try:
    retry_main_loop()
except Exception, e:
    pass
context.close()

2 个回答

1

根据这里提供的脚本链接,当你用kill -9命令结束程序时,进程ID文件会留下来。不过,这个脚本在重新启动时也能正确清理这些文件。

1

如果你在使用Linux系统,并且进程级别的锁是可以接受的,那就继续往下看。

我们尝试去获取这个锁。如果获取失败,就检查一下这个锁是否被某个正在运行的进程占用。如果没有被占用,就可以解除这个锁,然后继续进行。

from lockfile.pidlockfile import PIDLockFile
from lockfile import AlreadyLocked

pidfile = PIDLockFile("/var/run/mydaemon.pid", timeout=-1)
try:
    pidfile.acquire()
except AlreadyLocked:
    try:
        os.kill(pidfile.read_pid(), 0)
        print 'Process already running!'
        exit(1)
    except OSError:  #No process with locked PID
        pidfile.break_lock()

#pidfile can now be used to create DaemonContext

补充说明:看起来PIDLockFile这个功能只有在lockfile版本大于等于0.9时才可用。

撰写回答