2017-02-04 5 views
3

Может кто-нибудь объяснить, что случилось с ниже кодОшибка при использовании модуля многопроцессорности python с функцией генератора.

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",)'

Большое спасибо заранее.

+0

как о изменение доходности? – Shiping

+0

Я стараюсь избегать хранения значений. – Manu

+0

выход будет пытаться сохранить значение, а return вернет значение и забудет его. тем не менее доходность не будет работать. – Shiping

ответ

4

Вы должны использовать функцию не генератор здесь. Средства: измените yield на return, чтобы преобразовать sq в функцию. Pool не может работать с генераторами.

Кроме того, при попытке создать рабочую версию в Windows у меня возникло странное повторяющееся сообщение об ошибке.

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__" при запуске этого модуля:

from multiprocessing import Pool 

def sq(x): 
    return x**2 

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

результата :

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

Edit: если вы не хотите сохранять значения заранее вы можете использовать imap

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

n теперь является объектом генератора. Употреблять значения (и активировать фактическую обработку), я заставляю итерацию по списку, и я получаю тот же результат, как и выше

print(list(n)) 

Обратите внимание, что документация указывает на то, что imap гораздо медленнее, чем map

+0

Я стараюсь избегать хранения значений. – Manu

+0

см. Мое редактирование. –

+0

Я пробовал "если __name__ == '__main__'". Это та же ошибка. Я буду ждать предложений других людей, иначе я буду использовать опцию «возврат». – Manu

Смежные вопросы