gpt4 book ai didi

python - 如何从使用多处理运行脚本的python2子进程获取输出?

转载 作者:太空宇宙 更新时间:2023-11-04 00:25:35 24 4
gpt4 key购买 nike

这是我的演示代码。它包含两个脚本。

第一个是main.py,它会调用带有subprocess模块​​的print_line.py

第二个是 print_line.py,它将一些内容打印到标准输出。

主要.py

import subprocess

p = subprocess.Popen('python2 print_line.py',
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
close_fds=True,
shell=True,
universal_newlines=True)

while True:
line = p.stdout.readline()
if line:
print(line)
else:
break

打印线.py

from multiprocessing import Process, JoinableQueue, current_process


if __name__ == '__main__':
task_q = JoinableQueue()

def do_task():
while True:
task = task_q.get()
pid = current_process().pid
print 'pid: {}, task: {}'.format(pid, task)
task_q.task_done()

for _ in range(10):
p = Process(target=do_task)
p.daemon = True
p.start()

for i in range(100):
task_q.put(i)

task_q.join()

之前print_line.py是用threading和Queue模块写的,一切正常。但是现在,在更改为多处理模块后,main.py 无法从 print_line 获得任何输出。我尝试使用 Popen.communicate() 获取输出或在 Popen() 中设置 preexec_fn=os.setsid。它们都不起作用。

所以,这是我的问题:

  1. 为什么 subprocess 不能得到 multiprocessing 的输出?为什么线程没问题?

  2. 如果我注释掉 stdout=subprocess.PIPEstderr=subprocess.PIPE,输出将打印在我的控制台中。为什么?这是怎么发生的?

  3. 是否有机会从 print_line.py 获取输出?

最佳答案

好奇。

理论上这应该按原样工作,但事实并非如此。原因是在缓冲 IO 的深水、浑水中的某个地方。如果不刷新,子进程的子进程的输出似乎会丢失。

您有两个解决方法:

一种是在 print_line.py 中使用 flush():

def do_task():
while True:
task = task_q.get()
pid = current_process().pid
print 'pid: {}, task: {}'.format(pid, task)
sys.stdout.flush()
task_q.task_done()

这将解决问题,因为您将在向其写入内容后立即刷新标准输出。

另一种选择是在 main.py 中对 Python 使用 -u 标志:

p = subprocess.Popen('python2 -u print_line.py',
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
close_fds=True,
shell=True,
universal_newlines=True)

-u 将强制 stdin 和 stdout 在 print_line.py 中完全无缓冲,然后 print_line.py 的子级将继承它行为。

这些是解决问题的方法。如果您对发生这种情况的理论感兴趣,它肯定与子进程终止时丢失未刷新的标准输出有关,但我不是这方面的专家。

关于python - 如何从使用多处理运行脚本的python2子进程获取输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47626299/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com