我的python脚本可以产生一个无限期运行的进程吗?
我不太熟悉python,也不熟悉产生deamons,所以我想到了这个:
si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.CREATE_NEW_PROCESS_GROUP | subprocess.CREATE_NEW_CONSOLE
subprocess.Popen(executable, close_fds = True, startupinfo = si)
该过程继续运行python.exe,但是一关闭cmd窗口就会关闭。
答案 0 :(得分:14)
使用answer Janne Karila指出这是你可以运行一个在其父级死亡时不会死的过程,不需要使用win32process
模块。
DETACHED_PROCESS = 8
subprocess.Popen(executable, creationflags=DETACHED_PROCESS, close_fds=True)
DETACHED_PROCESS
是传递给基础Process Creation Flag函数的CreateProcess。
答案 1 :(得分:10)
这个问题是在3年前被问到的,尽管答案的基本细节没有改变,但鉴于它在Windows Python守护进程中的流行程度很高。搜索,我认为为了未来的Google到达者的利益添加一些讨论可能会有所帮助。
问题实际上有两个部分:
第一个答案是肯定的;正如已经指出的那样;将subprocess.Popen
与creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
关键字一起使用即可:
import subprocess
independent_process = subprocess.Popen(
'python /path/to/file.py',
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
)
请注意,至少根据我的经验,此处不需要CREATE_NEW_CONSOLE
。
话虽这么说,这个策略的行为与你对Unix守护进程的期望并不完全相同。什么构成一个表现良好的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)也是如此。特别是,它们无法改善信号处理的情况,并且它们无法轻松地从终端启动应用程序并在启动期间与其进行交互(例如,为您的脚本提供动态启动参数,例如,可能是密码,文件路径等),之前" daemonizing"。此外,Windows服务需要安装,尽管在第一次调用你的守护进程时可以在运行时快速完成安装。 - 修改用户的系统(注册表等),如果您来自Unix世界,这将是非常意外的。
鉴于此,我认为使用pythonw.exe
启动subprocess.CREATE_NEW_PROCESS_GROUP
子进程可能是与Python进程模拟传统Unix守护进程最接近的Windows等效。但是,这仍然会给您带来信号处理和启动通信的额外挑战(更不用说使您的代码平台依赖,这总是令人沮丧)。
尽管如此,对于将来遇到此问题的人,我已经推出了一个名为daemoniker的库,它包含了正确的Unix守护进程和上述策略。它还实现了信号处理(适用于Unix和Windows系统),并允许您将对象传递给"守护进程"使用泡菜的过程。最重要的是,它有一个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()
答案 2 :(得分:5)
为此目的,您可以守护您的python进程,或者当您使用Windows环境时,您希望将其作为Windows服务运行。
你知道我喜欢只发布网络链接:
但是根据您的要求提供更多信息:
A simple way to implement Windows Service.阅读所有可以解决疑问的评论
如果你真的想了解更多
首先阅读本文
什么是守护进程或creating-a-daemon-the-python-way
<强>更新强> 子流程不是实现这种事情的正确方法