我正在尝试学习如何使用multiprocessing
,但我无法让它发挥作用。以下是documentation
from multiprocessing import Process
def f(name):
print 'hello', name
if __name__ == '__main__':
p = Process(target=f, args=('bob',))
p.start()
p.join()
应该输出
'你好鲍勃'
但我得到了
>
没有错误或其他消息,它只是坐在那里,它在IDLE
中从一台带有32位版本的Python 2.7的Windows 7机器上保存的.py文件中运行
答案 0 :(得分:13)
我的猜测是你正在使用IDLE来尝试运行这个脚本。不幸的是,这个例子在IDLE中无法正常运行。请注意the docs开头的注释:
注意此程序包中的功能需要 main 模块可由孩子们输入。这在编程中有所涉及 然而,值得指出的是指导方针。这意味着一些 示例,例如multiprocessing.Pool示例将不起作用 互动翻译。
IDLE中的子节点无法导入__main__
模块,即使您将脚本作为具有IDLE的文件运行(通常使用F5)。
答案 1 :(得分:2)
有效。
我已经标记了使用评论运行示例所需的更改:
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
答案 2 :(得分:2)
问题不在于IDLE。问题是尝试在没有sys.stdout的进程中打印到sys.stdout。这就是Spyder遇到同样问题的原因。 Windows上的任何GUI程序都可能存在同样的问题。
在Windows上,至少GUI程序通常在没有stdin,stdout或stderr流的进程中运行。 Windows期望GUI程序通过在屏幕上绘制像素的小部件(图形中的G)与用户交互,并从Windows事件系统接收键和鼠标事件。这就是IDLE 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()
然后是'主线' block转到IDLE shell和'函数f'块进入控制台。
这个结果表明Justin Barber声称由IDLE运行的用户文件无法导入到多处理启动的进程中是不正确的。
编辑:Python在sys.__stdout__
中保存进程的原始标准输出。当IDLE在Windows上正常启动时,这是IDLE shell中的结果,作为纯GUI过程。
>>> sys.__stdout__
>>>
以下是从CommandPrompt启动IDLE时的结果。
>>> import sys
>>> sys.__stdout__
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
>>> sys.__stdout__.fileno()
1
stdin,stdout和stderr的标准文件号是0,1,2。使用
运行文件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()
IDLE中的在控制台中启动,输出相同。
答案 3 :(得分:1)
很可能您的主进程在刷新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)
作为最后一个语句。
答案 4 :(得分:0)
我遇到了多处理无法在Spyder上运行的问题,而且总是落在这里。我通过使用线程而不是多处理来解决它。如下所述:https://pymotw.com/2/threading/
import threading
def worker(num):
"""thread worker function"""
print 'Worker: %s' % num
return
threads = []
for i in range(5):
t = threading.Thread(target=worker, args=(i,))
threads.append(t)
t.start()
答案 5 :(得分:0)
尝试使用此代码(来自标准手册)。在 Windows 上对我有用。另一个也不适合我:)
ProxyPass /tomcat http://localhost:8080/tomcat