Windows服务(尽管在很多情况下是一个可行的替代方案)对我来说基本上是不可能的:它们不是跨平台的,而且需要修改代码。pythonw.exe(一个与所有最新的Windows Python二进制文件一起发布的windowless version of Python)更接近,但它仍然没有完全成功:特别是,它未能改善信号处理的情况,而且您仍然无法轻松地从终端启动一个pythonw.exe应用程序并在启动期间与之交互(例如,要向脚本传递动态启动参数,例如,密码、文件路径等,请在“守护”之前执行。
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()
这个问题已经有6年的历史了,但是我也遇到了同样的问题,而且现有的答案对于我的用例来说还不够跨平台。尽管Windows服务的使用方式通常与Unix守护进程类似,但归根结底,它们有很大的不同,而且“细节上是魔鬼”。长话短说,我开始尝试寻找一些东西,使我能够在Unix和Windows上运行完全相同的应用程序代码,同时尽可能在这两个平台上实现对性能良好的Unix守护进程(即better explained elsewhere)的期望:
os.umask
)STDIN
、STDOUT
和STDERR
重定向到不同的流(通常是DEVNULL
),并防止控制终端的重新获取SIGTERM
。跨平台守护进程的基本问题是,作为操作系统的Windows实际上不支持守护进程的概念:从终端(或在任何其他交互上下文中,包括从Explorer启动等)启动的应用程序将继续使用可见窗口运行,除非控制应用程序(在本例中为Python)包含无窗口GUI。此外,Windows信号处理严重不足,试图将信号发送到独立的Python进程(而不是子进程,子进程在终端关闭后将无法生存)几乎总是会导致Python进程立即退出而不进行任何清理(没有
finally:
,没有atexit
,没有__del__
等)。Windows服务(尽管在很多情况下是一个可行的替代方案)对我来说基本上是不可能的:它们不是跨平台的,而且需要修改代码。
pythonw.exe
(一个与所有最新的Windows Python二进制文件一起发布的windowless version of Python)更接近,但它仍然没有完全成功:特别是,它未能改善信号处理的情况,而且您仍然无法轻松地从终端启动一个pythonw.exe
应用程序并在启动期间与之交互(例如,要向脚本传递动态启动参数,例如,密码、文件路径等,请在“守护”之前执行。最后,我决定使用
subprocess.Popen
和creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
关键字创建一个独立的、无窗口的进程:然而,这仍然给我留下了启动通信和信号处理的额外挑战。对于前者,我的策略是:
pickle
启动进程命名空间的重要部分tempfile
在信号处理方面,我得有点创意。在“守护”进程中:
尽管如此,对于将来遇到这个问题的人来说,我已经将一个名为daemoniker的库打包成一个统一的facade,它将适当的Unix守护和上述Windows策略包装在一起。cross-platform API看起来如下:
在Windows中,它被称为“服务”,您可以很容易地实现它,例如使用win32serviceutil模块,它是pywin32的一部分。不幸的是,这两个“心智模型”(service vs daemon)在细节上非常不同,尽管它们的用途相似,而且我知道没有Python门面试图将它们统一到一个框架中。
我想到两个选择:
将程序导入a windows service。您可能可以在两个实现之间共享大部分代码。
你的程序真的使用任何守护程序功能吗?如果不是,则将其重写为在后台运行、通过套接字管理通信并执行其任务的简单服务器。它可能会比守护进程消耗更多的系统资源,但是它是独立于平台的。
相关问题 更多 >
编程相关推荐