4

У меня есть простой пример многопроцессорности, который я пытаюсь создать. Функция версия обычной карты() работает, но при изменении в Pool.map, я получаю странное сообщение об ошибке:Ошибка функции отображения многопроцессорности Python

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 должны быть сорваны. Module-level functions are picklable, но partial(f, y=y) не определен на уровне модуля и поэтому не подбирается.

Существует простое решение:

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

p.map(g, x) 

функции сделаны с functools.partial used to be unpickable. Однако, с python2.7 или лучше, вы можете также определить g (на уровне модуля) с помощью functools.partial:

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]. Но обратите внимание, чтобы получить этот результат f должен был быть определен с def, а не lambda. Я думаю, это потому, что pickle relies on "fully qualified" name references для поиска значений объектов объекта.

+0

Извините, я не совсем понимаю. У меня есть другой сценарий почти точно такой же, используя частичный, который работает, а это не так. Что сказать, что что-то определено на уровне модуля? Ahh, увидел ваше обновление --- да, def против лямбда - это точно разница между тем, который работал, и тем, который этого не делает. Благодаря! – Mittenchops