如何在 Linux 上管理基于 Python 的守护进程?

Posted

技术标签:

【中文标题】如何在 Linux 上管理基于 Python 的守护进程?【英文标题】:How do I manage a Python based daemon on Linux? 【发布时间】:2011-02-26 10:55:06 【问题描述】:

我有一个基于 Python 的工作程序,我想将其作为守护程序运行。目前我正在以一种非常骇人听闻的方式进行操作,从screen-d -m name 会话开始,然后用pkill -9 -f name 杀死它。

最终我不得不将它转移到我们在这里使用的更好的系统(因此我不愿意修改程序)但在此期间,我正在寻找一个更清洁的方式来做到这一点。

我目前的想法是将其作为 inti.d 脚本的后台任务启动,但我如何编写该部分以使其恢复正常?

【问题讨论】:

【参考方案1】:

有些模块可用于守护 Python 脚本。

python-daemon 实现了良好的守护进程规范 (PEP 3143)。

还有this module最近出现在github上,它似乎更pythonic且易于使用。

【讨论】:

【参考方案2】:

试试这个question 或更准确的解决方案。

【讨论】:

我真的不想搞砸程序的内部结构。哎呀,我宁愿保留我现在正在使用的东西,而不是那样做。 真的你不需要改变你的程序,如果它是可导入的。 Joust 在 deamon-example Run 方法中导入您的 main,(替换 while 循环)。【参考方案3】:

在 linux 上有一个 start-stop-daemon 实用程序作为 init.d 工具的一部分。

它非常灵活,允许以不同的方式捕获服务器的 pid。

还有一个文件 /etc/init.d/skeleton 可以作为您自己的 init.d 脚本的基础。

如果您的目标平台是基于 debian 的,那么创建一个 debina 包来部署它是有意义的,因为它还有助于将守护程序正确集成到系统的其余部分中。而且它并不太复杂(如果你之前做过十次的话;-)

【讨论】:

【参考方案4】:

如果你想用 python 中的代码来做,这是一个非常标准的 C 方法,它被移植到我使用的 python 中。它完美无瑕,您甚至可以选择文件输出。

import os
import signal
def daemonize(workingdir='.', umask=0,outfile='/dev/null'):
#Put in background
pid = os.fork()
if pid == 0:
    #First child
    os.setsid()
    pid = os.fork() #fork again
    if pid == 0:
        os.chdir(workingdir)
        os.umask(umask)
    else:
        os._exit(0)
else:
    os._exit(0)

#Close all open resources
try:
    os.close(0)
    os.close(1)
    os.close(2)
except:
    raise Exception("Unable to close standard output. Try running with 'nodaemon'")
    os._exit(1)

#Redirect output
os.open(outfile, os.O_RDWR | os.O_CREAT)
os.dup2(0,1)
os.dup2(0,2)

然后,您可以使用信号来捕获何时向程序发送了终止信号并很好地退出。来自Python Docs的示例

import signal, os

def handler(signum, frame):
    print 'Signal handler called with signal', signum
    raise IOError("Couldn't open device!")

# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)

# This open() may hang indefinitely
fd = os.open('/dev/ttyS0', os.O_RDWR)

signal.alarm(0)          # Disable the alarm

【讨论】:

【参考方案5】:

使用init.d 风格的脚本启动它是一个好方法。您可以使用 POSIX 信号将其取下来......请参阅 ***, Signal handling in Python。

【讨论】:

我可以kill -9 它,但我不知道如何可靠地找到它的PID。 @BCS: -9 通常是... 矫枉过正(请原谅双关语)。见kill -9。至于查找它的 PID,您的脚本可以在 /var/run 中创建一个 pidfile,或者使用允许您将 argv[0] 设置为一些易于识别的名称以与 pkill 一起使用的库。【参考方案6】:

PEP 3143 -- Standard daemon process library

【讨论】:

以上是关于如何在 Linux 上管理基于 Python 的守护进程?的主要内容,如果未能解决你的问题,请参考以下文章

『YQOI2019』失昼城的守星使 题解

python脚步管理工具supervisor=3.3.0的安装使用。基于linux系统。

基于Flask实现后台权限管理系统 - 导言

在Linux上创建webrev(cont)[基于svn]

详解如何在Centos6和Centos7两个版本上,执行Cobbler无人值守安装!

Linux 中的逻辑卷 LVM 管理完整初学者指南