使用带生成器功能的python多处理模块时出错

Error in use of python multiprocessing module with generator function.

有人能解释一下下面的代码有什么问题吗

1
2
3
4
5
6
from multiprocessing import Pool
def sq(x):
    yield x**2
p = Pool(2)

n = p.map(sq, range(10))

我有以下错误

MaybeEncodingError Traceback (most recent call
last) in ()
5 p = Pool(2)
6
----> 7 n = p.map(sq, range(10))

/home/devil/anaconda3/lib/python3.4/multiprocessing/pool.py in
map(self, func, iterable, chunksize)
258 in a list that is returned.
259 '''
--> 260 return self._map_async(func, iterable, mapstar, chunksize).get()
261
262 def starmap(self, func, iterable, chunksize=None):

/home/devil/anaconda3/lib/python3.4/multiprocessing/pool.py in
get(self, timeout)
606 return self._value
607 else:
--> 608 raise self._value
609
610 def _set(self, i, obj):

MaybeEncodingError: Error sending result: '[, ]'. Reason:
'TypeError("can't pickle generator objects",)'

非常感谢。


这里必须使用函数而不是生成器。方法:用returnyield改为函数。Pool不能与发电机一起工作。

此外,当尝试在Windows上创建一个工作版本时,我收到了一条奇怪的重复错误消息。

1
2
3
4
5
6
7
Attempt to start a new process before the current process
has finished its bootstrapping phase.

This probably means that you are on Windows and you have
forgotten to use the proper idiom in the main module:

if __name__ == '__main__':

从字面上引用我得到的评论,因为它是不言自明的:

the error on windows is because each process spawns a new python process which interprets the python file etc. so everything outside the"if main block" is executed again"

为了便于携带,在运行此模块时必须使用__name__=="__main__"

1
2
3
4
5
6
7
8
9
from multiprocessing import Pool

def sq(x):
    return x**2

if __name__=="__main__":
    p = Pool(2)
    n = p.map(sq, range(10))
    print(n)

结果:

1
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

编辑:如果不想预先存储值,可以使用imap

1
n = p.imap(sq, range(10))

n现在是一个生成器对象。为了使用这些值(并激活实际的处理),我通过一个列表强制迭代,得到与上面相同的结果

1
print(list(n))

请注意,文档显示imapmap慢得多。