4

작성하려고하는 간단한 다중 처리 예제가 있습니다. 일반 map() 함수 버전이 작동하지만 Pool.map으로 변경하면 이상한 오류가 발생합니다.파이썬 다중 처리 맵 함수 오류

from multiprocessing import Pool 
from functools import partial 
x = [1,2,3] 
y = 10 
f = lambda x,y: x**2+y 

# ordinary map works: 
map(partial(f,y=y),x) 
# [11, 14, 19] 

# multiprocessing map does not 
p = Pool(4) 
p.map(partial(f, y=y), x) 
Exception in thread Thread-2: 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner 
    self.run() 
    File "/usr/lib/python2.7/threading.py", line 504, in run 
    self.__target(*self.__args, **self.__kwargs) 
    File "/usr/lib/python2.7/multiprocessing/pool.py", line 319, in _handle_tasks 
    put(task) 
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed 

산 세척 오류? 정확히이게 뭐야?

답변

6

Pool.map에 대한 인수는 picklable이어야합니다. Module-level functions are picklable이지만 partial(f, y=y)은 모듈 수준에서 정의되지 않았으므로 선택할 수 없습니다. functools.partial used to be unpickable로 만든

def g(x, y=y): 
    return f(x, y) 

p.map(g, x) 

기능 :

간단한 해결 방법은. 그러나 Python2.7 이상으로, 당신은 또한 functools.partial를 사용 g (모듈 수준에서) 정의 할 수 있습니다 :

import multiprocessing as mp 
import functools 

def f(x, y): 
    return x**2 + y 

x = [1,2,3] 
y = 10 

g = functools.partial(f, y=y) 

if __name__ == '__main__': 
    p = mp.Pool() 
    print(p.map(g, x)) 

[11, 14, 19]를 얻을 수 있습니다. 그러나이 결과를 얻으려면 lambda 대신 def으로 정의해야합니다. 이것은 pickle relies on "fully qualified" name references이 함수 객체 값을 조회하기 때문이라고 생각합니다.

+0

죄송 합니다만, 나는 완전히 이해하지 못하고 있습니다 .- 부분적으로는 거의 똑같은 다른 스크립트가 있습니다. 모듈 수준에서 정의 된 것이 무엇입니까? Ahh, 당신의 업데이트를 보았습니다. 예, def 대 lambda는 정확하게 작동 한 것과 그렇지 않은 것의 차이입니다. 감사! – Mittenchops