Python多处理apply_async永远不会在Windows 7上返回结果

kyp*_*hos 5 python windows multiprocessing

我试图遵循一个非常简单的多处理示例:

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)]
Run Code Online (Sandbox Code Playgroud)

但是,在我的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>]
Run Code Online (Sandbox Code Playgroud)

如果我跑,results[0].ready()我总是得到False.

如果我运行results[0].get()python解释器冻结,等待获得永远不会到来的结果.

这个例子很简单,所以我认为这是一个与操作系统相关的低级错误(我在Windows 7上).但也许别人有更好的主意?

dan*_*ano 13

这里有几个错误.首先,在Windows上运行时必须声明Pool内部if __name__ == "__main__":警卫.其次,即使您只传递一个参数,也必须将关键字参数传递给序列.所以把它放在一起: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])
Run Code Online (Sandbox Code Playgroud)

输出:

[1, 8, 27, 64, 125, 216]
Run Code Online (Sandbox Code Playgroud)

编辑:

哦,正如moarningsun提到的multiprocessing 那样,在交互式解释器中效果不佳:

注意

此程序包中的功能要求__main__子程序可以导入该模块.这在编程指南中有所涉及,但值得在此指出.这意味着某些示例(例如multiprocessing.Pool示例)在交互式解释器中不起作用.

所以你需要实际执行代码作为脚本来正确测试它.


Aru*_*raj 5

我运行的是python 3,IDE在anaconda(windows)中是spyder,所以这个技巧对我不起作用。我尝试了很多,但没有任何效果。我有问题的原因,与达诺在他的笔记中列出的原因相同。但是经过一整天的搜索,我得到了一些解决方案,它帮助我在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)
Run Code Online (Sandbox Code Playgroud)

使用此功能后,上面的问题代码也做了如下更改:

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])
Run Code Online (Sandbox Code Playgroud)

我得到的输出为:

[1, 8, 27, 64, 125, 216]
Run Code Online (Sandbox Code Playgroud)

我认为这篇文章可能对某些Windows用户有用。