2

在蒔蘿序列化/酸洗中構建我的代碼的重要部分之後,我還試圖使用pathos多處理來並行化我的計算。悲傷是蒔蘿的自然延伸。如何運行嵌套的分層病態多處理映射?

當試圖運行嵌套

from pathos.multiprocessing import ProcessingPool 
ProcessingPool().map(fn, args) 

的其他ProcessingPool().map裏面,然後我得到:

AssertionError: daemonic processes are not allowed to have children 

例如爲:

from pathos.multiprocessing import ProcessingPool 

def triple(x): 
    return 3*x 

def refork(x): 
    from pathos.multiprocessing import ProcessingPool 
    return ProcessingPool().map(triple, xrange(5)) 

ProcessingPool().map(refork, xrange(3)) 

產量

AssertionError: daemonic processes are not allowed to have children 

我嘗試使用amap(...).get()沒有成功。這是在0.2.0的病態。

允許嵌套並行化的最佳方法是什麼?

更新

我必須說實話,在這一點上,和承認,我已刪除了從悲愴的斷言"daemonic processes are not allowed to have children"。我還內置了一些東西,級聯KeyboardInterrupt那些工人和工人...下面的部分解決方案:

def run_parallel(exec_func, exec_args, num_workers_i) 
    pool = ProcessingPool(num_workers_i) 
    pool.restart(force=True) 
    pid_is = pool.map(get_pid_i, xrange(num_workers_i)) 
    try: 
     results = pool.amap(
      exec_func, 
      exec_args, 
     ) 
     counter_i = 0 
     while not results.ready(): 
      sleep(2) 
      if counter_i % 60 == 0: 
       print('Waiting for children running in pool.amap() with PIDs: {}'.format(pid_is)) 
      counter_i += 1 
     results = results.get() 
     pool.close() 
     pool.join() 
    except KeyboardInterrupt: 
     print('Ctrl+C received, attempting to terminate pool...') 
     hard_kill_pool(pid_is, pool) # sending Ctrl+C 
     raise 
    except: 
     print('Attempting to close parallel after exception: {}'.format(sys.exc_info()[0])) 
     cls.hard_kill_pool(pid_is, pool) # sending Ctrl+C 
     raise 


def hard_kill_pool(pid_is, pool): 
    for pid_i in pid_is: 
     os.kill(pid_i, signal.SIGINT) # sending Ctrl+C 
    pool.terminate() 

似乎從控制檯和IPython的筆記本電腦(含停止按鈕)工作,但不知道它的正確率100%在所有的角落案件。

+0

我是'pathos'作者。你不能讓進程產生進程的原因是他們沒有適當地死亡,並且你有殭屍進程最終會掛起。我會推薦@Yoda的解決方案,因爲這是典型的情況......一個「昂貴的」並行塊和幾個「輕量級」並行工作位。 ''pathos'也有'ParallelPool',它比較慢,但是如果你需要線程以外的東西,它就可以工作。我還建議嘗試使用非阻塞映射,因爲阻塞會讓你放慢速度。另請參閱:http://stackoverflow.com/questions/28203774 –

+0

@MikeMcKerns,我開始在許多方面(包括非守護進程)嘗試代碼,並最終完成了上述工作。還包括'amap',但由於其他原因,'Ctrl + C'沒有讓我走出'map'。不幸的是不能使用「輕量級」技巧,因爲在尋找感傷時(蒔蘿之後)這已經是一個更大的系統。現在接下來的挑戰是擁有某種共享內存(讀寫所有進程),這似乎很難使用我的級聯解決方案...偉大的工具順便說一句,謝謝! –

+0

我無法想象你有什麼樣的工作流你不能使用其他池('ThreadingPool'或'ParallelPool')來提供嵌套並行性,並且需要層次結構ProcessingPools ...但也許你有一個我沒有想到的有效用例,我不介意更多地瞭解它(可能作爲''github'gosub頁面上的一張票)。是的,通過刪除斷言,嵌套'ProcessingPools'應該工作。然而,斷言存在的原因是嵌套的產卵池往往以殭屍的身份生存。使用他們的工作ID來殺死殭屍進程是一種解決方法。 –

回答

3

我遇到完全相同的問題。在我的情況下,內部操作是需要並行性的操作,所以我做了ThreadingPoolProcessingPool。這裏是你的例子:

from pathos.multiprocessing import ProcessingPool, ThreadingPool 

def triple(x): 
    return 3*x 

def refork(x): 
    from pathos.multiprocessing import ProcessingPool 
    return ProcessingPool().map(triple, xrange(5)) 

ThreadingPool().map(refork, xrange(3)) 

你甚至可以有另一個層與另一個外部線程池。根據您的情況,您可以反轉這些池的順序。但是,您不能擁有進程的進程。如果確實需要,請參閱:https://stackoverflow.com/a/8963618/6522112。我還沒有嘗試過,所以我不能詳細說明這一點。

+0

有道理,不幸的是,在我的情況下,我不能說哪個級別會提前大量計算,也不能容易地限制到2級並行化。 –

+0

我給出的解決方案似乎工作,但有時外池似乎永遠掛起。我沒有運氣就嘗試過'imap'和'amap'。也許@MikeMcKerns可以啓發這個? 'ParallelPool'可以提供幫助嗎? – Y0da

+0

本質上,python的'multiprocessing.Pool'不會乾淨地殺死它的父項。 'multiprocess'和''pathos'有相同的問題,因爲它們重複使用相同的代碼。 '''pathos.pools.ParallelPool'不會從'multiprocessing'(它來自'pp')分叉,因此它不會遇到同樣的問題......但是,序列化較弱(這是通過「源提取」來完成的,而不是「酸洗」,並且它不允許共享對象)。 –