Popen等待子进程,即使直接子进程已终止 [英] Popen waiting for child process even when the immediate child has terminated

查看:245
本文介绍了Popen等待子进程,即使直接子进程已终止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Windows 8/XP上使用Python 2.7.

I'm working with Python 2.7 on Windows 8/XP.

我有一个程序A,它使用以下代码运行另一个程序B:

I have a program A that runs another program B using the following code:

p = Popen(["B"], stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
return

B运行批处理脚本C.C是运行时间较长的脚本,即使C尚未完成,我也希望B退出.我已经使用以下代码(在B中)完成了此操作:

B runs a batch script C. C is a long running script and I want B to exit even though C has not finished. I have done it using the following code (in B):

p = Popen(["C"])
return

当我运行B时,它可以按预期运行.但是,当我运行A时,我希望它在B退出时退出.但是,即使B已经退出,A也会等到C退出.关于正在发生的事情以及可能的解决方案的任何想法?

When I run B, it works as expected. When I run A however, I expected it to exit when B exits. But A waits until C exits even though B has already exitted. Any ideas on what's happening and what possible solutions could be?

不幸的是,将A更改为B的明显解决方案不是一种选择.

Unfortunately, the obvious solution of changing A to look like B is not an option.

下面是一个功能性的示例代码来说明此问题: https://www.dropbox.com/s/cbplwjpmydogvu2/popen.zip ?dl = 1

Here is a functional sample code to illustrate this issue: https://www.dropbox.com/s/cbplwjpmydogvu2/popen.zip?dl=1

非常感谢任何输入.

推荐答案

您可以为C子进程提供start_new_session模拟:

You could provide start_new_session analog for the C subprocess:

#!/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]: CreateProcess的进程创建标志()

这篇关于Popen等待子进程,即使直接子进程已终止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆