Python subprocess.poll() 个问题
Python subprocess.poll() questions
我正在使用 Python 的子进程模块,在轮询 运行ning 进程时遇到问题。
我的最终目标是从 stdout
中获取每一行,评估它打印出主进程 stdout
的相关新行,因为它 运行s。问题是,当我轮询一个测试程序时,它似乎在等待子进程完成,然后再向 stdout
输出任何内容。当我向父程序引入一个time.sleep(1)
方法时它就是这样做的。
家长计划
import subprocess
import time
def runProcess():
process = subprocess.Popen([
'py.exe',
'subpy.py'],
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
while process.poll() == None:
print('.', end ="")
time.sleep(1)
runProcess()
input("press enter to exit.")
子程序
import random, time
for x in range(1,5):
time.sleep(1)
value = random.randint(1,3)
if value == 1:
print("hello")
if value == 2:
print('goodbye')
if value == 3:
print('im not sure')
exit()
如有任何帮助,我们将不胜感激!
PS:
我的 parent
过程的最终目标看起来像这样,尽管我不确定这是否会 运行 在输出完全完成之前进入轮询问题。
import subprocess
import time
def runProcess():
process = subprocess.Popen([
'py.exe',
'subpy.py'],
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
while process.poll() == None:
stdout, stderr = subprocess.communicate()
if stdout == '':
print('.', end ="")
time.sleep(1)
if stdout == "goodbye" or stdout == 'hello'
print(">>> %s" % stdout)
else:
print(stdout)
runProcess()
input("press enter to exit.")
创建进程后,可以读取其stdout
直到关闭,说明进程已经关闭。但是有几个问题。
首先是进程可能会填满 stderr
并阻止尝试写入更多内容。这可以通过为您读取 stderr 的后台线程来解决。在这个例子中,我只是将它复制到一个 in-memory 缓冲区中,以便在进程退出后读取。还有其他选项,具体取决于您要对数据流执行的操作。
然后是 stdout
管道多久冲洗一次的问题。由于它是一个管道,写入是块缓冲的。如果没有来自子进程的刷新,您将无法实时获得输出。在 unix-like 系统中,您可以用 pseudo-tty 替换管道(参见 pty 模块)。但这是 Windows,因此在调用过程中您无能为力。最终发生的事情是,你根据子库刷新的时间(或者你在代码中放置了很多刷新)来分组获取传入行。
import subprocess
import sys
import io
import time
import shutil
import threading
def runProcess():
process = subprocess.Popen([
sys.executable,
'subpy.py'],
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
process.stdin.close()
err_buf = io.BytesIO()
err_thread = threading.Thread(target=shutil.copyfileobj,
args=(process.stderr, err_buf))
err_thread.start()
for line in process.stdout:
line = line.decode() # defaulting to system encoding
print(line,end='',flush=True)
process.wait()
err_thread.join()
err_buf.seek(0)
print("Errors:", err_buf.read().decode())
runProcess()
input("press enter to exit.")
我正在使用 Python 的子进程模块,在轮询 运行ning 进程时遇到问题。
我的最终目标是从 stdout
中获取每一行,评估它打印出主进程 stdout
的相关新行,因为它 运行s。问题是,当我轮询一个测试程序时,它似乎在等待子进程完成,然后再向 stdout
输出任何内容。当我向父程序引入一个time.sleep(1)
方法时它就是这样做的。
家长计划
import subprocess
import time
def runProcess():
process = subprocess.Popen([
'py.exe',
'subpy.py'],
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
while process.poll() == None:
print('.', end ="")
time.sleep(1)
runProcess()
input("press enter to exit.")
子程序
import random, time
for x in range(1,5):
time.sleep(1)
value = random.randint(1,3)
if value == 1:
print("hello")
if value == 2:
print('goodbye')
if value == 3:
print('im not sure')
exit()
如有任何帮助,我们将不胜感激!
PS:
我的 parent
过程的最终目标看起来像这样,尽管我不确定这是否会 运行 在输出完全完成之前进入轮询问题。
import subprocess
import time
def runProcess():
process = subprocess.Popen([
'py.exe',
'subpy.py'],
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
while process.poll() == None:
stdout, stderr = subprocess.communicate()
if stdout == '':
print('.', end ="")
time.sleep(1)
if stdout == "goodbye" or stdout == 'hello'
print(">>> %s" % stdout)
else:
print(stdout)
runProcess()
input("press enter to exit.")
创建进程后,可以读取其stdout
直到关闭,说明进程已经关闭。但是有几个问题。
首先是进程可能会填满 stderr
并阻止尝试写入更多内容。这可以通过为您读取 stderr 的后台线程来解决。在这个例子中,我只是将它复制到一个 in-memory 缓冲区中,以便在进程退出后读取。还有其他选项,具体取决于您要对数据流执行的操作。
然后是 stdout
管道多久冲洗一次的问题。由于它是一个管道,写入是块缓冲的。如果没有来自子进程的刷新,您将无法实时获得输出。在 unix-like 系统中,您可以用 pseudo-tty 替换管道(参见 pty 模块)。但这是 Windows,因此在调用过程中您无能为力。最终发生的事情是,你根据子库刷新的时间(或者你在代码中放置了很多刷新)来分组获取传入行。
import subprocess
import sys
import io
import time
import shutil
import threading
def runProcess():
process = subprocess.Popen([
sys.executable,
'subpy.py'],
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
process.stdin.close()
err_buf = io.BytesIO()
err_thread = threading.Thread(target=shutil.copyfileobj,
args=(process.stderr, err_buf))
err_thread.start()
for line in process.stdout:
line = line.decode() # defaulting to system encoding
print(line,end='',flush=True)
process.wait()
err_thread.join()
err_buf.seek(0)
print("Errors:", err_buf.read().decode())
runProcess()
input("press enter to exit.")