我正在尝试遵循一个非常简单的多处理示例:
import multiprocessing as mp def cube(x): return x**3 pool = mp.Pool(processes=2) results = [pool.apply_async(cube, args=x) for x in range(1,7)]
然而,在我的Windows机器上,我无法得到的结果(在Ubuntu的12.04LTS它运行完美)。
如果我检查results
,我看到以下内容:
[<multiprocessing.pool.ApplyResult object at 0x01FF0910>, <multiprocessing.pool.ApplyResult object at 0x01FF0950>, <multiprocessing.pool.ApplyResult object at 0x01FF0990>, <multiprocessing.pool.ApplyResult object at 0x01FF09D0>, <multiprocessing.pool.ApplyResult object at 0x01FF0A10>, <multiprocessing.pool.ApplyResult object at 0x01FF0A50>]
如果我运行results[0].ready()
我总是得到False
。
如果我运行results[0].get()
python解释器冻结,等待得到的结果,永远不会到来。
这个例子是如此简单,所以我认为这是一个低级别的操作系统相关的错误(我在Windows 7上)。 但也许别人有更好的主意?
这里有一些错误。 首先, 在Windows上运行时 ,必须声明Pool
的if __name__ == "__main__":
guard。 其次,即使只传递一个参数,也必须传递args
关键字参数。 所以把它们放在一起:
import multiprocessing as mp def cube(x): return x**3 if __name__ == "__main__": pool = mp.Pool(processes=2) results = [pool.apply_async(cube, args=(x,)) for x in range(1,7)] print([result.get() for result in results])
输出:
[1, 8, 27, 64, 125, 216]
编辑:
呵呵,正如moarningsun所提到的那样, multiprocessing
在交互式解释器中工作不好 :
注意
该包中的功能要求
__main__
模块可由孩子导入。 编程指南中介绍了这一点,但值得在这里指出。 这意味着一些例子,如multiprocessing.Pool
例子在交互式解释器中不起作用。
所以你需要实际执行代码作为脚本来正确地测试它。
我正在运行python 3,而IDE在anaconda(windows)中是spyder,所以这个技巧对我来说不起作用。 我尝试了很多,但没有任何区别。 我得到了我的问题的原因,也是在他的笔记中由dano列出。 但经过漫长的一天搜索,我得到了一些解决方案,它帮助我运行相同的代码我的Windows机器。 本网站帮助我获得解决方案:
http://python.6.x6.nabble.com/Multiprocessing-Pool-woes-td5047050.html
自从我使用python 3以后,我改变了这个程序:
from types import FunctionType import marshal def _applicable(*args, **kwargs): name = kwargs['__pw_name'] code = marshal.loads(kwargs['__pw_code']) gbls = globals() #gbls = marshal.loads(kwargs['__pw_gbls']) defs = marshal.loads(kwargs['__pw_defs']) clsr = marshal.loads(kwargs['__pw_clsr']) fdct = marshal.loads(kwargs['__pw_fdct']) func = FunctionType(code, gbls, name, defs, clsr) func.fdct = fdct del kwargs['__pw_name'] del kwargs['__pw_code'] del kwargs['__pw_defs'] del kwargs['__pw_clsr'] del kwargs['__pw_fdct'] return func(*args, **kwargs) def make_applicable(f, *args, **kwargs): if not isinstance(f, FunctionType): raise ValueError('argument must be a function') kwargs['__pw_name'] = f.__name__ # edited kwargs['__pw_code'] = marshal.dumps(f.__code__) # edited kwargs['__pw_defs'] = marshal.dumps(f.__defaults__) # edited kwargs['__pw_clsr'] = marshal.dumps(f.__closure__) # edited kwargs['__pw_fdct'] = marshal.dumps(f.__dict__) # edited return _applicable, args, kwargs def _mappable(x): x,name,code,defs,clsr,fdct = x code = marshal.loads(code) gbls = globals() #gbls = marshal.loads(gbls) defs = marshal.loads(defs) clsr = marshal.loads(clsr) fdct = marshal.loads(fdct) func = FunctionType(code, gbls, name, defs, clsr) func.fdct = fdct return func(x) def make_mappable(f, iterable): if not isinstance(f, FunctionType): raise ValueError('argument must be a function') name = f.__name__ # edited code = marshal.dumps(f.__code__) # edited defs = marshal.dumps(f.__defaults__) # edited clsr = marshal.dumps(f.__closure__) # edited fdct = marshal.dumps(f.__dict__) # edited return _mappable, ((i,name,code,defs,clsr,fdct) for i in iterable)
在这个函数之后,上面的问题代码也是这样改变的:
from multiprocessing import Pool from poolable import make_applicable, make_mappable def cube(x): return x**3 if __name__ == "__main__": pool = Pool(processes=2) results = [pool.apply_async(*make_applicable(cube,x)) for x in range(1,7)] print([result.get(timeout=10) for result in results])
我得到的输出为:
[1, 8, 27, 64, 125, 216]
我在想这个帖子可能对一些windows用户有用。