Dev*_*oka 11 python multiprocessing
我正在努力学习如何使用,multiprocessing但我无法让它工作.以下是文档中的代码
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)
它应该输出
'你好鲍勃'
但我得到了
>
没有错误或其他消息,它只是坐在那里,它是IDLE从具有32位版本的Python 2.7的Windows 7机器上保存的.py文件运行的
πόδ*_*κύς 15
我的猜测是你正在使用IDLE来尝试运行这个脚本.不幸的是,这个例子在IDLE中无法正常运行.请注意文档开头的注释:
注意此程序包中的功能要求主 模块可由子项导入.这在编程指南中有所涉及,但值得在此指出.这意味着某些示例(例如multiprocessing.Pool示例)在交互式解释器中不起作用.
__main__即使您将脚本作为具有IDLE的文件(通常使用F5)运行,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 首先运行,它用通过套接字与 IDLE 本身交互的对象替换标准流的 None 。然后它 exec() 的用户代码。当用户代码运行 multiprocessing 时,multiprocessing 会启动没有 std 流的进一步进程,但永远不会得到它们。
解决的办法是在控制台启动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()
Run Code Online (Sandbox Code Playgroud)
然后'main line'块进入IDLE shell,'function f'块进入控制台。
这个结果表明,贾斯汀·巴伯关于 IDLE 运行的用户文件无法导入到由多进程启动的进程的说法是不正确的。
编辑:Python 将进程的原始标准输出保存在sys.__stdout__. 下面是在 Windows 上正常启动 IDLE 时 IDLE 的 shell 中的结果,作为一个纯 GUI 进程。
>>> sys.__stdout__
>>>
Run Code Online (Sandbox Code Playgroud)
下面是从 CommandPrompt 启动 IDLE 时的结果。
>>> import sys
>>> sys.__stdout__
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
>>> sys.__stdout__.fileno()
1
Run Code Online (Sandbox Code Playgroud)
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()
Run Code Online (Sandbox Code Playgroud)
在控制台中启动IDLE并且输出是相同的。