首页 > 解决方案 > 如何重定向 multiprocessing.Process 的标准输出

问题描述

我正在使用 Python 3.7.4,我创建了两个函数,第一个函数使用multiprocessing.Process执行可调用,第二个函数只打印“Hello World”。在我尝试重定向标准输出之前,一切似乎都运行良好,这样做会阻止我在流程执行期间获得任何打印值。我已将示例简化到最大程度,这是我目前遇到的问题代码。

这些是我的功能:

import io
import multiprocessing
from contextlib import redirect_stdout


def call_function(func: callable):
    queue = multiprocessing.Queue()                                      
    process = multiprocessing.Process(target=lambda:queue.put(func()))
    process.start()          

    while True:
        if not queue.empty():
            return queue.get()


def print_hello_world():
    print("Hello World")

这有效:

call_function(print_hello_world)

前面的代码工作并成功打印“Hello World”

这不起作用:

with redirect_stdout(io.StringIO()) as out:
    call_function(print_hello_world)
print(out.getvalue())

使用前面的代码,我没有在控制台中打印任何内容。

任何建议将不胜感激。我已经能够将问题缩小到这一点,我认为这与 io.StringIO() 已经关闭后结束的过程有关,但我不知道如何检验我的假设,更不知道如何实施解决方案。

标签: python-3.xpython-multiprocessingstringioredirectstandardoutput

解决方案


这是我找到的解决方法。似乎如果我使用文件而不是 StringIO 对象,我可以让事情正常工作。

with open("./tmp_stdout.txt", "w") as tmp_stdout_file:
    with redirect_stdout(tmp_stdout_file):
        call_function(print_hello_world)
    stdout_str = ""
    for line in tmp_stdout_file.readlines():
        stdout_str += line
    stdout_str = stdout_str.strip()

print(stdout_str)  # This variable will have the captured stdout of the process

另一件可能很重要的事情是多处理库缓冲标准输出,这意味着打印仅在函数执行/失败后显示,为了解决这个问题,您可以在需要时在函数中强制标准输出刷新在这种情况下,调用将在print_hello_world内部(实际上,我必须为守护进程执行此操作,如果它运行超过指定时间则需要终止)

sys.stdout.flush()  # This will force the stdout to be printed 

推荐阅读