2011-08-02 27 views
4

已解決:問題是Wingware Python IDE。我想現在自然的問題是如何可能以及如何解決這個問題。multiprocessing.Pool似乎在Windows中工作,但不在Ubuntu?

昨天我問了一個問題(Problem with multiprocessing.Pool in Python),這個問題幾乎一樣,但我發現它似乎在Windows計算機上工作,而不是在我的Ubuntu上。在這篇文章的最後,我會發佈一個稍微不同的代碼版本,做同樣的事情。

我的問題的簡短摘要:在Python中使用multiprocessing.Pool時,我並不總是能夠獲得我要求的工作量。發生這種情況時,程序就會停止。

我一直在爲解決方案整天工作,然後我開始考慮諾亞斯對我以前的問題的評論。他說,它在他的機器上工作,所以我將代碼交給了我的同事,他使用Enthoughts 64位Python 2.7.1發行版運行Windows機器。我和我在ubuntu上運行的巨大差異一樣。我還提到我們都有Wingware Python IDE,但我懷疑這是否重要?

當我的同事在他的機器上運行代碼時,我的代碼有兩個問題不會出現。

  1. 我並不總是能夠得到我要求的四名工人(雖然我的機器有12名工人)。當發生這種情況時,這個過程就會停止並且不會繼續。沒有異常或錯誤發生。

  2. 當我能夠得到我要求的四名工人(發生約1次5次左右)時,生成的數字(普通的隨機數)對於所有四張照片都是完全相同的。我的同事並非如此。

東西很腥,我非常感謝你們提供的任何幫助。

代碼:

import multiprocessing as mp 
import scipy as sp 
import scipy.stats as spstat 
import pylab 

def testfunc(x0, N): 
    print 'working with x0 = %s' % x0 
    x = [x0] 
    for i in xrange(1,N): 
     x.append(spstat.norm.rvs(size = 1)) # stupid appending to make it slower 
     if i % 10000 == 0: 
      print 'x0 = %s, i = %s' % (x0, i) 
    return sp.array(x) 

def testfuncParallel(fargs): 
    return testfunc(*fargs) 


# Define Number of tasks. 
nTasks = 4 
N = 100000 

if __name__ == '__main__': 

    """ 
    Try number 1. Using multiprocessing.Pool together with Pool.map_async 
    """ 
    pool = mp.Pool(processes = nTasks) # I have 12 threads (six cores) available so I am suprised that it does not get access to nTasks = 4 amount of workers 

    # Define tasks: 
    tasks = [(x, n) for x, n in enumerate(nTasks*[N])] # nTasks different tasks 

    # Compute parallel: async - asynchronically, i.e. not necessary in order. 
    result = pool.map_async(testfuncParallel, tasks) 

    pool.close() # These are needed if map_async is used 
    pool.join() 

    # Get results: 
    sim = sp.zeros((N, nTasks)) 

    for nn, res in enumerate(result.get()):  
     sim[:, nn] = res 

    pylab.figure() 
    for i in xrange(nTasks): 
     pylab.subplot(nTasks,1, i + 1) 
     pylab.plot(sim[:, i]) 

    pylab.show() 

在此先感謝。

真誠, 馬蒂亞斯

+1

這似乎在Enthought的Python 2.7.1 [EPD 7.0-2(64位)]我的64位Ubuntu盒子上工作。我已經多次運行你的代碼,似乎無法讓它停止。 – NPE

+0

謝謝。我真的不知道什麼區別我的機器和其餘部分:( – matiasq

+0

所以這與隨機數字生成沒有關係?我很困惑,從網上閱讀看來,期望的行爲是每個進程應該表現出完全相同的方式,所以一個人必須重置隨機種子? –

回答

1

更新:原來這不得不無關,與matplotlib或後端,而是用多,一般相關的錯誤。我們已經爲Wing版本4.0.4+修復了這個問題。解決方法是不要在子進程中執行的代碼中設置斷點。

它似乎是Wing IDE的matplotlib支持Tkinter後端與多處理嚴重交互。當我嘗試這個例子時,它在TCL/Tk代碼中崩潰。我懷疑在Windows上工作的人使用了不同的matplotlib後端。

在「擴展」選項卡下的「項目屬性」中關閉「matplotlib事件循環支持」似乎可以解決此問題。

或者,當「matplotlib事件循環支持」打開時,添加以下內容似乎可以解決這個問題。

進口matplotlib matplotlib.use( 'WXAgg')

如果你有WXAgg後端這隻會工作。 Wing IDE支持的其他後端(即使調試過程暫停,繪圖仍保持交互的方式)是GTKAgg和Qt4Agg,但我還沒有嘗試過。

我會看看我能否找到並修復這個bug。我懷疑我們需要在進程ID更改時禁用我們的事件循環支持。感謝您報告這一點。

+0

那麼這與隨機數生成無關?我很困惑,從在線閱讀看來,期望的行爲似乎是每個進程都應該以完全相同的方式運行,所以必須重置隨機種子? –

4

我沒有爲你的第一個問題的解決方案。事實上,我可以在Enthought的Python 2.7.1 [EPD 7.0-2(64位)]的64位Ubuntu機器上反覆運行你的代碼。 編輯:原來問題是由您的IDE(Wingware)造成的。明顯的解決方法是從IDE外部運行腳本。

至於第二個問題,會發生什麼情況是,在Unix上,每個工作進程都從父進程繼承了隨機數生成器的相同狀態。這就是他們產生相同的僞隨機序列的原因。所有您需要做什麼來解決這個電話scipy.random.seedtestfunc頂部:

def testfunc(x0, N): 
    sp.random.seed() 
    print 'working with x0 = %s' % x0 
    ... 
+0

感謝您對第二個問題的幫助。關於第一個問題,您認爲使用IDE可能會導致問題嗎?我知道這聽起來很愚蠢,但這是我們唯一的區別。設置,我可以想出 – matiasq

+1

@matiasq:這很容易測試,只需從命令行運行你的代碼,看看是否有幫助:'/ path/to/epd/bin/python script.py',其中'/path/to/epd/bin'指向Python二進制文件,'script.py'是您腳本的名字。 – NPE

+0

當然,我現在太累了:)。謝謝。這就是它。如果我在Wingware之外運行它,它將起作用。令人驚訝的是,一個簡單的編輯可以做這樣的傷害。 – matiasq

相關問題