2017-02-04 27 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

yield會嘗試保存該值,返回值只會返回值並忘記它。然而收益率不起作用。 – 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] 

編輯:如果你不想存儲值事先可以使用imap

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

n現在是一個生成器對象。消耗值(並激活實際處理),我強迫迭代通過列表,我也得到了同樣的結果如上

print(list(n)) 

注意的是,文件表明,imapmap

+0

我試圖避免存儲值。 – Manu

+0

然後看我的編輯。 –

+0

我試過「if __name__ =='__main__'」。這是一樣的錯誤。 我會等待別人的建議,否則我會用「返回」選項。 – Manu

相關問題