我希望我的Python程序可以作为守护进程在Windows或Unix上后台运行。我看到python-daemon包只适用于Unix系统;是否有跨平台的替代品?如果可能,我希望保持代码尽可能简单。
我希望我的Python程序可以作为守护进程在Windows或Unix上后台运行。我看到python-daemon包只适用于Unix系统;是否有跨平台的替代品?如果可能,我希望保持代码尽可能简单。
在Windows中,它被称为"服务",您可以使用win32serviceutil模块实现它,该模块是pywin32的一部分,这可以很容易地实现。不幸的是,“服务”与“守护进程”的两种“思维模式”在细节上非常不同,尽管它们具有类似的用途,但我不知道任何Python外观尝试将它们统一成一个单一的框架。
os.umask
)STDIN
、STDOUT
和STDERR
重定向到不同的流(通常为DEVNULL
),并防止重新获取控制终端SIGTERM
。finally:
、没有atexit
、没有__del__
等)。
对我来说,Windows服务虽然在许多情况下是可行的替代方案,但基本上不是一个问题:它们不跨平台,并且需要进行代码修改。附带所有最近的Windows Python二进制文件的 无窗口版本Python pythonw.exe
更接近解决问题,但仍然不够完美:特别是在信号处理方面,它无法改善情况,而且您仍然不能轻松地从终端启动pythonw.exe
应用程序并在启动期间与其交互(例如,为了向脚本传递动态启动参数,比如密码、文件路径等),在“守护”之前。
最终,我选择使用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的库,它包装了适当的Unix守护进程和上述Windows策略,形成了一个统一的外观。 跨平台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()
我能想到的有两个选项:
将你的程序移植成Windows服务。你可以在两个实现之间共享大部分代码。
你的程序是否真正需要任何守护进程功能?如果不需要,那么将其重写为一个简单的后台运行服务器,通过套接字管理通信并执行任务。这可能会消耗比守护进程更多的系统资源,但是相对来说具有平台无关性。