Nic*_*ton 22 python daemon cross-platform
我希望我的Python程序在后台作为守护进程在Windows或Unix上运行.我看到python-daemon包仅适用于Unix; 是否有跨平台的替代方案?如果可能的话,我想保持代码尽可能简单.
这个问题已有6年历史了,但是我遇到了同样的问题,现有的答案还不足以适用于我的用例。尽管Windows服务通常以与Unix守护程序相似的方式使用,但最终它们还是有很大的不同,并且“细节上是魔鬼”。长话短说,我着手尝试寻找可以使我在Unix和Windows上运行完全相同的应用程序代码的东西,同时尽可能地满足对行为良好的Unix守护程序(在其他地方有更好的解释)的期望。在两个平台上:
os.umask
在Python世界中)STDIN
,STDOUT
和重定向STDERR
到不同的流(通常为DEVNULL
),并防止重新获得控制终端SIGTERM
。跨平台守护程序的基本问题是,作为操作系统,Windows确实不支持守护程序的概念:从终端启动的应用程序(或在任何其他交互式上下文中,包括从Explorer启动的应用程序)将除非控制应用程序(在此示例中为Python)包含无窗口的GUI,否则继续使用可见窗口运行。此外,Windows信号处理严重不足,尝试将信号发送到独立的 Python进程(与子进程相反,子进程无法在终端关闭后继续存在)几乎总是导致该Python进程立即退出而没有任何清理(否finally:
,否atexit
,否__del__
等)。
Windows服务(尽管在许多情况下是可行的替代方法)对我基本上是不可能的:它们不是跨平台的,它们将需要修改代码。pythonw.exe
(所有最近的Windows Python二进制文件都随附了Python的无窗口版本),但它仍然没有达到目标:特别是,它无法改善信号处理的情况,并且您仍然无法轻松启动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
)
Run Code Online (Sandbox Code Playgroud)
但是,这仍然给我带来了启动通信和信号处理方面的额外挑战。对于前者,我不做过多介绍,我的策略是:
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()
Run Code Online (Sandbox Code Playgroud)
我想到了两个选择:
将您的程序移植到Windows 服务中。您可能可以在两个实现之间共享大部分代码。
您的程序真的使用任何守护程序功能吗?如果没有,您可以将其重写为一个在后台运行的简单服务器,通过套接字管理通信并执行其任务。它可能会比守护进程消耗更多的系统资源,但它将独立于引用平台。
归档时间: |
|
查看次数: |
7801 次 |
最近记录: |