使用python多处理模块创建的子进程将无法打印

Joh*_*ohn 18 python printing multiprocessing

我有下面的代码的问题,以及print在子进程中使用该函数的任何代码.我看不到任何印刷的陈述,即使我用sys.std[err|out].write('worker')而不是print.

这是代码(来自官方python文档):

from multiprocessing import Process

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

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()
Run Code Online (Sandbox Code Playgroud)

输出为空白.

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

import threading

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

if __name__ == '__main__':
    p = threading.Thread(target=f, args=('bob',))
    p.start()
    p.join()
Run Code Online (Sandbox Code Playgroud)

输出:hello bob

你能指点我解决方案吗?提前致谢.

Tam*_*más 28

试试这个:

from multiprocessing import Process
import sys

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

...
Run Code Online (Sandbox Code Playgroud)

AFAIK multiprocessing模块生成的处理标准输出是缓冲的,因此只有缓冲区变满或显式刷新时才会看到输出sys.stdout.

  • 好吧,IDLE很奇怪.为了"捕获"使用`print`语句或`sys.stdout.write`编写的所有内容,IDLE"覆盖"`sys.stdout`并将其替换为将所有内容传递回IDLE的对象,以便它可以打印它.我想当你从`multiprocessing`开始一个新的进程时,这个hackery不会被子进程继承,因此你在IDLE中看不到任何东西.但我只是在这里猜测,我目前没有Windows机器来检查它. (4认同)
  • 它适用于 Windows,但您会在主 CMD 进程中看到打印的消息。就我而言,这是我启动 jupyter 的 CMD 窗口。 (2认同)

man*_*est 7

多处理的文档清楚地解释了为什么这不起作用!

"注意:此包中的功能要求子进程可以导入__main__方法.这在编程指南中有所涉及,但值得指出这一点.这意味着一些示例,例如multiprocessing.Pool示例将无法在互动翻译."


Rob*_*ing 5

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