Python多处理示例不起作用

Python多处理示例不起作用,python,multiprocessing,Python,Multiprocessing,我正在尝试学习如何使用多处理,但我无法让它工作。这里是代码的权利,从 它应该输出 “你好,鲍勃” 但是我得到了 > 没有错误或其他消息,它只是坐在那里,它在Windows 7机器上的一个保存的.py文件中以IDLE运行,使用32位版本的Python 2.7运行 我已使用注释标记了使示例运行所需的更改: from multiprocessing import Process def f(name): print 'hello', name #indent if __name__ == '__m

我正在尝试学习如何使用
多处理
,但我无法让它工作。这里是代码的权利,从

它应该输出

“你好,鲍勃”

但是我得到了

>

没有错误或其他消息,它只是坐在那里,它在Windows 7机器上的一个保存的.py文件中以
IDLE
运行,使用32位版本的Python 2.7运行

我已使用注释标记了使示例运行所需的更改:

from multiprocessing import Process

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

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()` # remove ` (grave accent)
结果:

from multiprocessing import Process

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

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()
将笔记本电脑另存为ex1.py后的输出:

reuts@reuts-K53SD:~/python_examples$ cat ex1.py 
#!/usr/bin/env python
from multiprocessing import Process

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

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()
reuts@reuts-K53SD:~/python_examples$ python ex1.py 
hello bob

我猜您正在使用IDLE来尝试运行此脚本。不幸的是,此示例无法在空闲状态下正确运行。请注意以下内容开头的注释:

注意:此软件包中的功能要求主 模块不能由子模块导入。这在编程中有介绍 然而,这里值得指出的是。这意味着 示例,例如multiprocessing.Pool示例在中不起作用 交互式口译员


\uuuu main\uuuu
模块不可由IDLE中的子模块导入,即使您将脚本作为文件以IDLE方式运行(通常使用F5执行此操作)。

最有可能在刷新sysout之前退出主进程。试试这个:

from multiprocessing import Process
import sys

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

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()
    # make sure all output has been processed before we exit
    sys.stdout.flush()

如果这不起作用,请尝试添加
time.sleep(1)
作为最后一条语句。

我遇到了一个问题,即多处理在Spyder上不起作用,并且总是在这里登陆。我用线程而不是多重处理解决了这个问题。如下所述:


这个问题并非空穴来风。问题是试图在没有sys.stdout的进程中打印到sys.stdout。这就是为什么Spyder也有同样的问题。Windows上的任何GUI程序都可能有相同的问题

至少在Windows上,GUI程序通常在没有stdin、stdout或stderr流的进程中运行。Windows希望GUI程序通过在屏幕上绘制像素(图形中的G)的小部件与用户交互,并从Windows事件系统接收按键和鼠标事件。这就是空闲GUI使用tcl tk GUI框架的tkinter包装器所做的

当IDLE在子流程中运行用户代码时,idlelib.run首先运行,它将标准流的None替换为通过套接字与IDLE自身交互的对象。然后是exec()的用户代码。当用户代码运行多处理时,多处理将启动没有std流但从未获得它们的进一步进程

解决方案是在控制台中启动IDLE:
python-m idlelib.IDLE
(3.x上不需要
.IDLE
)。在控制台中启动的进程将std流连接到控制台。进一步的子流程也是如此。所有进程的真正标准输出(与sys.stdout相反)是控制台。如果运行文档中的第三个示例

from multiprocessing import Process
import os

def info(title):
    print(title)
    print('module name:', __name__)
    print('parent process:', os.getppid())
    print('process id:', os.getpid())

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

if __name__ == '__main__':
    info('main line')
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()
然后,“主线”块进入空闲外壳,“功能f”块进入控制台

这一结果表明,Justin Barber关于IDLE运行的用户文件不能导入多处理启动的进程的说法是不正确的

编辑:Python将进程的原始标准输出保存在
sys.\uu标准输出\uuu
中。当IDLE作为一个纯GUI进程在Windows上正常启动时,下面是IDLE外壳中的结果

>>> sys.__stdout__
>>> 
以下是从CommandPrompt启动IDLE时的结果

>>> import sys
>>> sys.__stdout__
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
>>> sys.__stdout__.fileno()
1
在控制台中以怠速启动,输出相同。

尝试使用此代码(来自标准手册)。在windows上为我工作。另一个也不适合我:)



您的打印声明是否真的不符合def?绿色是指缩进?是的,它在实际代码中正确缩进,这是我在发布时犯的一个错误。你是否将代码保存在一个文件中并运行它?@ReutSharabani是的,这有关系吗?@Chuckfullinata只是确保你不是从REPL事件中执行的。这两个都是我在发布问题时犯的错误,这两种代码都不存在于实际代码中,它们不会做任何事情。正如您所看到的,这段代码确实有效。要么您使用的代码与我发布的代码不同,要么问题不在于代码。你在哪里运行代码?你是怎么运作的?需要更多信息。问题可能是Windows特有的,我不知道。即使在Windows上,如果从命令行空闲运行,输出也是可见的。看到我的答案了,我不是在交互界面上运行的interpreter@Chuck您从何处运行它?硬盘上保存的
.py
文件drive@Chuck你是如何运行该文件的?@Chuck Fulinata这正是问题所在。这是行不通的,因为即使您以.py文件的形式运行脚本,
\uuuuu main\uuuu
模块在空闲状态下也不能被子模块导入。尽管这可能行得通,但请记住,这段代码是文档中逐字记录的,另一张海报已经注意到它可以工作。代码很好,您就是看不到输出。多处理行为取决于您运行它的特定计算机,而您的计算机的速度可能足以在您看到输出之前吞下输出。请随意进行向下投票,但请留下评论,以便我可以改进答案。当没有要刷新的标准时,刷新不是问题。有一个标准数据流可以解决这个问题。请参阅我的答案。虽然这在理论上可以回答这个问题,但在这里包括答案的基本部分,并提供链接供参考。Sami,如果您可以从控制台命令行启动Spyder,输出应该是可见的,因为它是空闲的。(你是在Windows上运行还是???)Terry,我没有试过,是的,我正在Windows上运行。卡尔:谢谢,我已经添加了一些例子。
>>> sys.__stdout__
>>> 
>>> import sys
>>> sys.__stdout__
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
>>> sys.__stdout__.fileno()
1
from multiprocessing import Process
import sys

def f(name):
    print('hello', name)
    print(sys.__stdout__)
    print(sys.__stdout__.fileno())
if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()
import multiprocessing as mp

    def foo(q):
        q.put('hello')
    
    if __name__ == '__main__':
        mp.set_start_method('spawn')
        q = mp.Queue()
        p = mp.Process(target=foo, args=(q,))
        p.start()
        print(q.get())
        p.join()