【问题标题】:Child processes created with python multiprocessing module won't print使用 python 多处理模块创建的子进程不会打印
【发布时间】:2011-02-16 00:06:31
【问题描述】:

我对下面的代码以及在子进程中使用print 函数的任何代码有疑问。即使我使用sys.std[err|out].write('worker') 而不是print,我也看不到任何打印的报表。

这是代码(from the official python documentation):

from multiprocessing import Process

def f(name):
    print 'hello', name

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()

输出为空白。

注意:以下代码使用线程模块并打印输出:

import threading

def f(name):
    print 'hello', name

if __name__ == '__main__':
    p = threading.Thread(target=f, args=('bob',))
    p.start()
    p.join()

输出hello bob

能否请您指出解决方案?提前致谢。

【问题讨论】:

  • Python 2.7.15 (Mac) 两个程序都输出hello bob。这可能是特定于平台的。
  • 你可以在运行python解释器时尝试将-u参数添加到它吗?它应该取消缓冲您的输出。 (类似于 python -u myscript.py)

标签: python printing multiprocessing


【解决方案1】:

试试这个:

from multiprocessing import Process
import sys

def f(name):
    print 'hello', name
    sys.stdout.flush()

...

AFAIK 由 multiprocessing 模块生成的已处理标准输出被缓冲,因此只有当缓冲区已满或您明确刷新 sys.stdout 时,您才会看到输出。

【讨论】:

  • 你在哪个平台上?以上适用于我在 Mac OS X 上;事实上,即使不刷新 sys.stdout,它也可以工作。
  • Tamas,我正在开发的平台是win32。顺便说一句,直到现在我都尝试在 IDLE 中运行代码。今天我尝试使用以下语法从命令行运行它:python.exe my_prog.py 并且它有效。有人知道为什么吗?以及如何通过在 IDLE 中运行程序来显示打印输出?
  • 好吧,IDLE 是个奇怪的东西。为了“捕获”您使用print 语句或sys.stdout.write 编写的所有内容,IDLE“覆盖”sys.stdout 并将其替换为将所有内容传递回IDLE 的对象,以便它可以打印它。我猜当你从multiprocessing 开始一个新进程时,这个hackery 不会被子进程继承,因此你在IDLE 中看不到任何东西。但我只是在这里猜测,我目前没有 Windows 机器来检查它。
  • 在 Windows 上安装了吗?
  • 它在 Windows 上工作,但您会在主 CMD 进程中看到打印的消息。在我的例子中,它是我启动 jupyter 的 CMD 窗口。
【解决方案2】:

多处理的文档清楚地解释了why 这行不通!

"注意:此包中的功能要求 __main__ 方法可由子级导入。这在编程指南中有所介绍,但在此值得指出。这意味着某些示例,例如 multiprocessing.Pool 示例不会在交互式解释器中工作。”

【讨论】:

  • 首先感谢您的回答。我所做的是将代码写入名为“example.py”的文件中,然后按 F5 运行它。也许这意味着“在 IDLE 中运行代码”? PS:我是一个 python 新手,很抱歉我可能在这里说的任何(过于)明显的事情。
  • 啊,是的,带有“>>”提示符的 IDLE 算作交互式解释器。因此,除非您将代码写入文件并按您所说的按 F5 或在命令提示符下键入“python example.py”,否则多处理基本上不会起作用。我可以理解这可能是一个令人困惑的问题。不客气。
  • @manifest 你能告诉我该怎么做吗? stackoverflow.com/questions/59892469/…
【解决方案3】:

我自己也遇到过这个问题,有时这可能是因为子进程实际上在到达 print 语句之前就默默地失败了。如果是这种情况,将子进程代码包装在 try-except 块中并返回异常对象(将在父进程中打印)是一种有效的调试方法。

【讨论】:

    【解决方案4】:

    我使用的是 PyCharm IDE,通过检查运行/调试配置中的“在输出控制台中模拟终端”字段,它打印了所需的结果。

    希望对您使用 PyCharm 有所帮助。

    【讨论】:

    • p.run() 是在子类化threading.Threadmultiprocessing.Process 时有意义的内部函数。不打算直接调用。通过直接调用p.run(),您只需运行赋予类构造函数的函数。函数本身不在线程/进程中运行,而是直接在主程序中运行。
    • 感谢您的解释。我想我应该删除我的答案以防止误导。
    • 我建议是的,
    • 这是唯一对我有用的解决方案。 (Pycharm)
    猜你喜欢
    • 2019-10-23
    • 2017-11-13
    • 1970-01-01
    • 2010-12-17
    • 2016-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多