【问题标题】:subprocess.communicate() hangs on Windows 8 if parent process creates some child如果父进程创建了一些子进程,则 subprocess.communicate() 在 Windows 8 上挂起
【发布时间】:2013-05-07 14:16:21
【问题描述】:

我有一个在 Win 2003 上运行良好的简单代码:

proc = subprocess.Popen('<some python script which runs another process>', stdout = subprocess.PIPE, stderr = subprocess.PIPE, stdin = subprocess.PIPE)
out = proc.communicate()[0]

但是在 Windows 8 上这部分; out = proc.communicate()[0],挂起。

有人看过这个问题吗?

  • 我检查了进程是否真的终止了(当子进程启动时 PID 不存在)
  • 制作proc.stdout.readlines()也是个问题,也挂了。如何检查标准输出是否有 EOF?
  • 当我停止子进程 proc.communicate() 工作正常。

这是最简单的例子:

import subprocess
proc = subprocess.Popen([sys.executable, "D:\\test.py"], stdout = subprocess.PIPE)
print 'PID', proc.pid #When this PID is printed I see in the taskbr that process is already finished
print 'Output', proc.communicate() # but this part is hangs

和代码 od test.py:

import os, time
from subprocess import Popen, PIPE

CREATE_NEW_PROCESS_GROUP = 0x00000200  # note: could get it from subprocess
DETACHED_PROCESS = 0x00000008          # 0x8 | 0x200 == 0x208


p = Popen("start /B notepad", shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE,
          creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
print 'Done'
exit()

这是有效的场景吗?

【问题讨论】:

  • 两件事,首先尝试从 windows cmd 手动运行命令,以确保命令正常工作。其次,您是否尝试使用shell=True 标志运行它?
  • 命令在 cmd 中工作正常,shell 标志并不重要 - 两个标志都不起作用。问题出在子进程中 - 在它运行时 - 尽管父进程已终止,但我无法从父进程获取输出。
  • 一个认为你可以做的调试你的程序是在一个while循环中使用proc.stdout.readline()函数并打印输出行来查看进程搁浅的时间。
  • 进程标准输出是否很长(超过 64kb)?因为当进程标准输出超过 64kb 时,我在 windows 中使用 subprocess.PIPE 时遇到问题。
  • 我也见过... 注意:subprocess.Popen 从最父脚本调用的进程不必是 python 脚本。它也可以是一个批处理文件,它使用start some-process.exe 来启动一个后台进程。

标签: python windows subprocess


【解决方案1】:

要让.communicate() 在不等待孙子(记事本)退出的情况下返回,您可以在test.py 中尝试:

import sys
from subprocess import Popen, PIPE

CREATE_NEW_PROCESS_GROUP = 0x00000200
DETACHED_PROCESS = 0x00000008

p = Popen('grandchild', stdin=PIPE, stdout=PIPE, stderr=PIPE,
          creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)

Popen waiting for child process even when the immediate child has terminated

【讨论】:

  • 我在 test.py 中进行了更改。它看起来像你的('grandchild' = 'C://Windows/System32/notepad.exe')。当我单独运行 test.py 时,即使在记事本运行时 p.communicate() 进程也不会完成。但是当我在主文件中运行 test.py 作为子进程时 - .communicate() 仍然挂起
  • 为避免歧义,您能否将修改后的 test.py 的确切代码添加到问题中。如果 grandchild="start notepad" (+shell=True) 会发生什么?
  • 当我不使用标准输出到 PIPE 时它可以工作:p = Popen('grandchild', close_fds = True, creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)。所以,这个解决方案适合我。感谢您的回答!
猜你喜欢
  • 2022-12-30
  • 2014-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-02
  • 1970-01-01
  • 2011-10-26
相关资源
最近更新 更多