我在Windows 8 / XP上使用Python 2.7。
我有一个程序A使用以下代码运行另一个程序B:
p = Popen(["B"], stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
return
B运行一个批处理脚本C. C是一个长时间运行的脚本,我希望B退出,即使C还没有完成。我使用以下代码完成了它(在B中):
p = Popen(["C"])
return
当我运行B时,它按预期工作。然而,当我运行A时,我预计它会在B退出时退出。但是A等到C退出,即使B已经退出了。关于发生了什么以及可能的解决方案的任何想法?
不幸的是,将A改为看起来像B的明显解决方案不是一种选择。
以下是用于说明此问题的功能示例代码: https://www.dropbox.com/s/cbplwjpmydogvu2/popen.zip?dl=1
非常感谢任何输入。
答案 0 :(得分:17)
您可以为start_new_session
子流程提供C
模拟:
#!/usr/bin/env python
import os
import sys
import platform
from subprocess import Popen, PIPE
# set system/version dependent "start_new_session" analogs
kwargs = {}
if platform.system() == 'Windows':
# from msdn [1]
CREATE_NEW_PROCESS_GROUP = 0x00000200 # note: could get it from subprocess
DETACHED_PROCESS = 0x00000008 # 0x8 | 0x200 == 0x208
kwargs.update(creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
elif sys.version_info < (3, 2): # assume posix
kwargs.update(preexec_fn=os.setsid)
else: # Python 3.2+ and Unix
kwargs.update(start_new_session=True)
p = Popen(["C"], stdin=PIPE, stdout=PIPE, stderr=PIPE, **kwargs)
assert not p.poll()
答案 1 :(得分:0)
以下是根据Sebastian的回答和this答案修改的代码段:
#!/usr/bin/env python
import os
import sys
import platform
from subprocess import Popen, PIPE
# set system/version dependent "start_new_session" analogs
kwargs = {}
if platform.system() == 'Windows':
# from msdn [1]
CREATE_NEW_PROCESS_GROUP = 0x00000200 # note: could get it from subprocess
DETACHED_PROCESS = 0x00000008 # 0x8 | 0x200 == 0x208
kwargs.update(creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP, close_fds=True)
elif sys.version_info < (3, 2): # assume posix
kwargs.update(preexec_fn=os.setsid)
else: # Python 3.2+ and Unix
kwargs.update(start_new_session=True)
p = Popen(["C"], stdin=PIPE, stdout=PIPE, stderr=PIPE, **kwargs)
assert not p.poll()
我只在Windows上亲自测试过。