Python:使用 PID 文件守护进程

Posted

技术标签:

【中文标题】Python:使用 PID 文件守护进程【英文标题】:Python: Daemonizing process with PID file 【发布时间】:2013-06-17 05:23:22 【问题描述】:

我正在尝试使用daemon 模块来守护进程。代码看起来像这样

import sys
import time
import daemon
import lockfile 


def do_things():
    while True:
        print "hello"
        time.sleep(3)

def main()
    context = daemon.DaemonContext(stdout=sys.stdout, 
                                   pidfile=lockfile.FileLock('test.pid'))

    with context:
        do_things()

现在您可以看到我正在创建一个锁定 PID 文件。现在我运行这个程序,它运行良好。现在为了测试 PID/daemon 功能,我使用启动另一个程序实例

python test.py

现在它不应该运行,因为之前的实例已经在运行。结果是第二个实例开始并进入一个循环(这个不是我的测试函数中的while 循环)。在此第二个实例上运行 strace 会连续提供以下输出

 stat("/some-path-here/Talha@Fedora14-4e1a9720.21520", st_mode=S_IFREG|0666,
 st_size=0, ...) = 0
 select(0, NULL, NULL, NULL, 0, 100000) = 0 (Timeout)

 link("/some-path-here/Talha@Fedora14-  4e1a9720.21520", 
 "/somepath/test.pid.lock") = -1 EEXIST (File exists)

而且这个痕迹会一直出现,直到进程被强制终止。 lockfile 函数确实检测到存在现有的锁定文件,但问题是程序没有退出。我也希望这个错误显示 pid 文件已经存在。

如何做到这一点?

【问题讨论】:

【参考方案1】:

注意:此答案假定您使用的是python-daemon 库。

守护程序库带有一个帮助类daemonDaemonRunner,它处理创建 pid 文件。查看其内部结构,它使用daemon.pidfile.TimeoutPIDLockFile 作为锁定文件的类型。

所以,看起来您可以通过以下任一方式解决此问题:

使用daemon.DaemonRunner(我们发现这个使用起来非常方便) 将 pidfile 的类型更改为 daemon.pidfile.TimeoutPIDLockFile

【讨论】:

我尝试了第二种方法,结果更糟。工作目录中没有pid文件,它还在抱怨它的存在!我通过 strace 确认 strace 给出 "open("test.pid", O_WRONLY|O_CREAT|O_EXCL, 0644) = -1 EEXIST (文件存在)"

以上是关于Python:使用 PID 文件守护进程的主要内容,如果未能解决你的问题,请参考以下文章

python并发编程(守护进程,进程锁,进程队列)

Redis配置

守护进程的创建过程

php程序守护进程

如何指定守护进程的日志和pid目录?

Linux Guard Service - 守护进程分裂