Python 多处理示例不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21198857/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python multiprocessing example not working
提问by Devon M
I am trying to learn how to use multiprocessingbut I can't get it to work. Here is the code right out of the documentation
我正在尝试学习如何使用,multiprocessing但我无法让它工作。这是文档中的代码
from multiprocessing import Process
def f(name):
print 'hello', name
if __name__ == '__main__':
p = Process(target=f, args=('bob',))
p.start()
p.join()
it should output
它应该输出
'hello bob'
'你好鲍勃'
but instead i get
但我得到了
>
>
no errors or other messages, it just sits there, It is running in IDLEfrom a saved .py file on a Windows 7 machine with the 32-bit version of Python 2.7
没有错误或其他消息,它只是坐在那里,它IDLE从 Windows 7 机器上保存的 .py 文件中运行,使用 32 位版本的 Python 2.7
采纳答案by π?δα? ?κ??
My guess is that you are using IDLE to try to run this script. Unfortunately, this example will not run correctly in IDLE. Note the comment at the beginning of the docs:
我的猜测是您正在使用 IDLE 来尝试运行此脚本。不幸的是,这个例子不能在 IDLE 中正确运行。请注意文档开头的注释:
Note Functionality within this package requires that the mainmodule be importable by the children. This is covered in Programming guidelines however it is worth pointing out here. This means that some examples, such as the multiprocessing.Pool examples will not work in the interactive interpreter.
注意 此包中的功能要求主模块可由子模块导入。这在编程指南中有介绍,但值得在这里指出。这意味着某些示例,例如 multiprocessing.Pool 示例在交互式解释器中将不起作用。
The __main__module is not importable by children in IDLE, even if you run the script as a file with IDLE (which is commonly done with F5).
该__main__模块不能被 IDLE 中的孩子导入,即使您使用 IDLE 将脚本作为文件运行(通常使用 F5 完成)。
回答by Reut Sharabani
It works.
有用。
I've marked the changes needed to make your sample run using comments:
我已经使用注释标记了使您的示例运行所需的更改:
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)
result:
结果:
from multiprocessing import Process
def f(name):
print 'hello', name
if __name__ == '__main__':
p = Process(target=f, args=('bob',))
p.start()
p.join()
Output from my laptop after saving it as ex1.py:
将笔记本电脑另存为 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
回答by miraculixx
Most likely your main process exits before sysout is flushed. Try this:
很可能您的主进程在 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()
If this doesn't work, try adding time.sleep(1)as the last statement.
如果这不起作用,请尝试添加time.sleep(1)为最后一个语句。
回答by Sami
I had the issue that multiprocessing did not work on Spyder, and always landed here. I solved it by using threading instead of multiprocessing. as described here: https://pymotw.com/2/threading/
我遇到的问题是多处理在 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()
回答by Terry Jan Reedy
The problem is not IDLE. The problem is trying to print to sys.stdout in a process that has no sys.stdout. That is why Spyder has the same problem. Any GUI program on Windows is likely to have the same problem.
问题不是空闲。问题是试图在没有 sys.stdout 的进程中打印到 sys.stdout。这就是为什么 Spyder 有同样的问题。Windows 上的任何 GUI 程序都可能有同样的问题。
On Windows, at least, GUI programs are usually run in a process without stdin, stdout, or stderr streams. Windows expects GUI programs to interact with users through widgets that paint pixels on the screen (the G in Graphical) and receive key and mouse events from Windows event system. That is what the IDLE GUI does, using the tkinter wrapper of the tcl tk GUI framework.
至少在 Windows 上,GUI 程序通常在没有 stdin、stdout 或 stderr 流的进程中运行。Windows 期望 GUI 程序通过在屏幕上绘制像素(图形中的 G)的小部件与用户交互,并从 Windows 事件系统接收键和鼠标事件。这就是 IDLE GUI 所做的,使用 tcl tk GUI 框架的 tkinter 包装器。
When IDLE runs user code in a subprocess, idlelib.run runs first, and it replaces None for the standard streams with objects that interact with IDLE itself through a socket. Then it exec()s user code. When the user code runs multiprocessing, multiprocessing starts further processes that have no std streams, but never get them.
当 IDLE 在子进程中运行用户代码时, idlelib.run 首先运行,它用通过套接字与 IDLE 本身交互的对象替换标准流的 None 。然后它 exec() 的用户代码。当用户代码运行 multiprocessing 时,multiprocessing 会启动没有 std 流的进一步进程,但永远不会得到它们。
The solution is to start IDLE in a console: python -m idlelib.idle(the .idleis not needed on 3.x). Processes started in a console get std streams connect to the console. So do further subprocesses. The real stdout (as opposed to the sys.stdout) of all the processes is the console. If one runs the third example in the doc,
解决的办法是在控制台启动IDLE: python -m idlelib.idle(在.idle不需要上3.X)。在控制台中启动的进程将 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()
then the 'main line' block goes to the IDLE shell and the 'function f' block goes to the console.
然后'main line'块进入IDLE shell,'function f'块进入控制台。
This result shows that Justin Barber's claim that the user file run by IDLE cannot be imported into processes started by multiprocessing is not correct.
这个结果表明,贾斯汀·巴伯关于 IDLE 运行的用户文件无法导入到由多进程启动的进程的说法是不正确的。
EDIT: Python saves the original stdout of a process in sys.__stdout__. Here is the result in IDLE's shell when IDLE is started normally on Windows, as a pure GUI process.
编辑:Python 将进程的原始标准输出保存在sys.__stdout__. 下面是在 Windows 上正常启动 IDLE 时 IDLE 的 shell 中的结果,作为一个纯 GUI 进程。
>>> sys.__stdout__
>>>
Here is the result when IDLE is started from CommandPrompt.
下面是从 CommandPrompt 启动 IDLE 时的结果。
>>> import sys
>>> sys.__stdout__
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
>>> sys.__stdout__.fileno()
1
The standard file numbers for stdin, stdout, and stderr are 0, 1, 2. Run a file with
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()
in IDLE started in the console and the output is the same.
在控制台中启动IDLE并且输出是相同的。

