如何在Windows上分离Python子进程(没有setsid)?
我正在将一些进程代码迁移到Windows,这在Posix上运行得很好。简单地说:启动子流程并立即分离的代码将不起作用,因为如何在Windows上分离Python子进程(没有setsid)?,python,windows,python-2.7,winapi,Python,Windows,Python 2.7,Winapi,我正在将一些进程代码迁移到Windows,这在Posix上运行得很好。简单地说:启动子流程并立即分离的代码将不起作用,因为setsid()不可用: import os, subprocess, sys p = subprocess.Popen([sys.executable, '-c', "print 'hello'"], preexec_fn=os.setsid) 我可以取消使用setsid,但当父进程结束时,子进程结束 我的问题是如何在Windows上实现与setsid相同的效果,从而使子
setsid()
不可用:
import os, subprocess, sys
p = subprocess.Popen([sys.executable, '-c', "print 'hello'"], preexec_fn=os.setsid)
我可以取消使用setsid
,但当父进程结束时,子进程结束
我的问题是如何在Windows上实现与setsid
相同的效果,从而使子进程生命周期独立于父进程的生命周期?
我愿意使用一个特定的Python包,如果有这样一个包的话。例如,我已经在使用
psutil
,但我没有看到任何对我有帮助的东西。RbMn对我的问题的评论实际上就是答案。不需要分离,因为Windows中的进程始终是顶级对象。我尝试了一个睡眠任务,效果很好
但是正如埃里克森在这里的评论中指出的那样,关闭控制台窗口将导致子进程终止。我还遇到了一些Windows上女服务员和Popen的稳定性问题,我想我已经解决了,添加了以下代码,设置了一些并使用了close\u fds
:
if 'nt' == os.name:
flags = 0
flags |= 0x00000008 # DETACHED_PROCESS
flags |= 0x00000200 # CREATE_NEW_PROCESS_GROUP
flags |= 0x08000000 # CREATE_NO_WINDOW
pkwargs = {
'close_fds': True, # close stdin/stdout/stderr on child
'creationflags': flags,
}
p = subprocess.Popen([sys.executable, '-c', cmd], **pkwargs)
在windows中,子进程生存期独立于父进程。它未“附加”到父进程。是和否。默认情况下,进程继承其父进程的进程组。组ID用于将console
CTRL\u C\u事件
和CTRL\u BREAK\u事件
发送到属于组的进程。此外,当控制台关闭时,连接到它的所有进程都会收到CTRL\u CLOSE\u事件
警告,并将在5秒后强制终止。由于一个进程被标记为控制台窗口(通常是分配进程)的有效所有者,因此通过taskill.exe或任务管理器杀死该所有者会将WM_CLOSE
发送到控制台窗口,并终止连接到控制台的每个进程。要获取新控制台,使用创建标志CREATE_NEW_CONSOLE
或CREATE_NO_WINDOW
(即不带窗口的新控制台)。要跳过连接到任何控制台,请使用分离\u进程
。要创建新组,请使用create\u new\u PROCESS\u group
。对于后者,默认情况下,如果连接到控制台,则在子级中禁用Ctrl+C;它可以通过SetConsoleCtrlHandler
手动启用。工作起来很有魅力,(ish)我使用了一个微妙的变化p=subprocess.Popen([sys.executable,cmd],**pkwargs)
。也适用于Python3.6.x。