2014-06-23 25 views
13

我想使用multiprocessing.Pool並行應用函數。 問題是,如果一個函數調用觸發了分段錯誤,則該池永遠掛起。 有沒有人有一個想法,我怎樣才能使一個池,檢測什麼時候這樣的事情發生並引發錯誤?multiprocessing.Pool掛起,如果子項導致分段錯誤

下面的示例演示如何重現它(需要scikit學習> 0.14)

import numpy as np 
from sklearn.ensemble import gradient_boosting 
import time 

from multiprocessing import Pool 

class Bad(object): 
    tree_ = None 


def fit_one(i): 
    if i == 3: 
     # this will segfault              
     bad = np.array([[Bad()] * 2], dtype=np.object) 
     gradient_boosting.predict_stages(bad, 
             np.random.rand(20, 2).astype(np.float32), 
             1.0, np.random.rand(20, 2)) 
    else: 
     time.sleep(1) 
    return i 


pool = Pool(2) 
out = pool.imap_unordered(fit_one, range(10)) 
# we will never see 3 
for o in out: 
    print o 
+2

修復分段錯誤?通常,段錯誤是由無效的內存訪問引起的,這是_undefined_行爲,並且根本不保證會導致段錯誤。 –

+0

沒有答案,但我可以說joblib.Parallel似乎永遠掛起。從我可以告訴的是,沒有辦法返回segfault或在多處理中添加「看門狗」超時。 –

+1

其實,也許你可以添加一個超時裝飾器?如顯示在這裏:http://code.activestate.com/recipes/577028/ –

回答

1

而不是使用Pool().imap()也許你寧願手動創建子進程自己與Process()。我敢打賭,返回的對象會讓你獲得任何孩子的活躍狀態。你會知道他們是否掛斷電話。

0

我還沒有運行你的例子,看它是否可以處理錯誤,但嘗試併發期貨。只需用您的fit_one(i)替換my_function(i)即可。保持__name__=='__main__':結構。併發期貨似乎需要這個。下面的代碼在我的機器上進行了測試,因此希望能夠直接適用於您的機器。

import concurrent.futures 

def my_function(i): 
    print('function running') 
    return i 

def run(): 
    number_processes=4 
    executor = concurrent.futures.ProcessPoolExecutor(number_processes) 
    futures = [executor.submit(my_function,i) for i in range(10)] 
    concurrent.futures.wait(futures) 

    for f in futures: 
     print(f.result()) 

if __name__ == '__main__': 
    run() 
+0

需要python 3.2 – Ninga

+0

我只是想這可能會起作用,因爲你可以在完成所有過程後返回的可調整'期貨'上調用各種方法。所以它可能會在步伐中承擔錯誤。 – Ninga

0

正如評論描述,如果你使用concurrent.Futures.ProcessPoolExecutor而不是multiprocessing.Pool這只是工作在Python 3。

如果你被困在Python 2中,我發現的最佳選擇是對Pool.apply_asyncPool.map_async返回的結果對象使用timeout參數。例如:

pool = Pool(2) 
out = pool.map_async(fit_one, range(10)) 
for o in out: 
    print o.get(timeout=1000) # allow 1000 seconds max 

只要您有一個子進程完成任務需要多長時間的上限,就可以工作。

1

這是一個known bug, issue #22393, in Python。只要您使用multiprocessing.pool,直到它被修復,就沒有有意義的解決方法。該鏈接提供了一個補丁程序,但尚未將其集成到主要版本中,因此沒有穩定的Python版本可以解決該問題。