我想让我的Python程序在Windows或Unix上作为守护进程在后台运行。我看到python-daemon package仅适用于Unix;是否有跨平台的替代方案?如果可能的话,我想保持代码尽可能简单。
答案 0 :(得分:10)
在Windows中,它被称为“服务”,您可以非常轻松地实现它,例如使用win32serviceutil模块,pywin32的一部分。不幸的是,两个“心理模型” - 服务与守护进程 - 在细节上有很大的不同,即使它们用于类似的目的,我知道没有Python外观试图将它们统一到一个框架中。
答案 1 :(得分:4)
有两种选择:
将您的计划移植到a windows service。您可以在两个实现之间共享大部分代码。
您的程序是否真的使用任何守护程序功能?如果没有,您将其重写为在后台运行的简单服务器,通过套接字管理通信并执行其任务。它可能比守护进程消耗更多的系统资源,但它会引用平台独立的。
答案 2 :(得分:4)
这个问题是6岁,但我遇到了同样的问题,现有的答案对于我的用例来说并不是跨平台的。虽然Windows服务通常以与Unix守护程序类似的方式使用,但在一天结束时它们大不相同,并且“细节中的魔鬼”。长话短说,我开始尝试找到能让我在Unix和Windows上运行完全相同的应用程序代码的东西,同时满足对行为良好的Unix守护进程(better explained elsewhere)的期望。尽可能在两个平台上:
os.umask
)STDIN
,STDOUT
和STDERR
重定向到不同的流(通常为DEVNULL
),并阻止重新获取控制终端SIGTERM
。跨平台守护进程的根本问题在于,Windows作为一个操作系统,实际上不支持守护进程的概念:从终端开始的应用程序(或任何其他交互式环境中的应用程序,包括从资源管理器启动,除非控制应用程序(在本例中为Python)包含无窗口GUI,否则将继续以可见窗口运行。此外,Windows信号处理严重不足,并且尝试将信号发送到独立的 Python进程(与子进程相反,后者无法在终端关闭后继续存在)几乎总会导致立即退出Python流程没有任何清理(没有finally:
,没有atexit
,没有__del__
等等。
Windows服务(虽然在许多情况下是一种可行的替代方案)对我来说基本上是不可能的:它们不是跨平台的,它们将需要代码修改。 pythonw.exe
(与所有最近的Windows Python二进制文件一起提供的windowless version of Python更接近,但它仍然没有完全削减:特别是,它无法改善信号处理的情况,而你仍然无法轻松地从终端启动pythonw.exe
应用程序并在启动期间与其进行交互(例如,为您的脚本提供动态启动参数,例如,密码,文件路径等),之前“daemonizing”。
最后,我决定使用subprocess.Popen
和creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
关键字来创建一个独立的,无窗口的过程:
import subprocess
independent_process = subprocess.Popen(
'/path/to/pythonw.exe /path/to/file.py',
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
)
然而,这仍然给我带来了启动通信和信号处理的额外挑战。对于前者,没有详细说明,我的策略是:
pickle
启动过程'命名空间tempfile
对于信号处理,我必须更有创意。在“守护进程”过程中:
所有人都说,对于将来遇到此问题的任何人,我已经推出了一个名为daemoniker的库,它将上述Windows策略的正确Unix守护程序和包装成统一的正面。 cross-platform API看起来像这样:
from daemoniker import Daemonizer
with Daemonizer() as (is_setup, daemonizer):
if is_setup:
# This code is run before daemonization.
do_things_here()
# We need to explicitly pass resources to the daemon; other variables
# may not be correct
is_parent, my_arg1, my_arg2 = daemonizer(
path_to_pid_file,
my_arg1,
my_arg2
)
if is_parent:
# Run code in the parent after daemonization
parent_only_code()
# We are now daemonized, and the parent just exited.
code_continues_here()
答案 3 :(得分:2)
通常,守护进程的概念是特定于Unix的,特别是关于文件创建掩码,进程层次结构和信号处理的预期行为。
您可能会发现PEP 3143很有用,其中对于Python 3.2考虑了python-daemon的建议延续,并讨论了许多related daemonizing modules and implementations。
答案 4 :(得分:0)
它仅仅是unix的原因是daemons是一个特定于Unix的概念,即由os启动的后台进程,通常作为根PID的子进程运行。
Windows没有直接等效的unix守护进程,我能想到的最接近的是Windows服务。
有一个名为pythonservice.exe的程序用于Windows。不确定它是否支持所有版本的python但