1

我有我想要執行並行幾次,但只有在同一時間所定義的數量的實例的功能。如何限制併發工人的數量?

自然的方式來做到這一點似乎是使用multiprocessing.Pool。具體來說,文件說,

頻繁模式(...)是允許 游泳池內的工人正在退出之前只完成工作的一組量,被 清理和新工藝催生取代舊的。該 maxtasksperchild參數池暴露這種能力最終 用戶。

maxtasksperchild被定義爲:

maxtasksperchild是一個工作進程可以 完成之前,它會退出,並且用新工人 工藝所取代,以使未使用的資源被釋放的任務數。默認 maxtasksperchild是無,這意味着工作進程會活得 只要池。

我不清楚什麼任務在這裏的意思。如果我想有,說,並行運行我的工人最多隻有4個實例,我應該開始multiprocessing.Pool作爲

pool = multiprocessing.Pool(processes=4, maxtasksperchild=4) 

如何processesmaxtasksperchild一起工作?莫非我設置processes 10和仍然只有4個工人正在運行(實際上有空閒6個過程?)

+0

當你做一個'p.map(F,S)''那裏是p'一個'Pool',s'算作一個任務序列'的每個元素。 'p.apply(f)'被視爲一項任務。 –

+0

你得到了'maxtasksperchild'的全部錯誤。但是,*爲什麼*要保留6個空閒進程?這比創建只有4個實際工作的流程更好嗎? – shx2

+0

@DanD。謝謝 - 一旦另一項任務完成,任務會被任何進程使用(我的情況是4)? (他們正在排隊處理?) – WoJ

回答

2

正如doc說(也是在你的說明),

過程是並行工作的人數可能一起運行,如果未設置,則它將與計算機中的CPU編號相同。

maxtasksperchild是最大數量的任務,每個進程可以處理,的,這意味着如果任務數完成達到maxtasksperchild,這一進程將被殺死,一個新的進程將開始加入到池

設我檢查代碼:

def f(x): 
    print "pid: ", os.getpid(), " deal with ", x 
    sys.stdout.flush() 

if __name__ == '__main__': 
    pool = Pool(processes=4, maxtasksperchild=2) 
    keys = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
    result = pool.map(f, keys) 

這裏我們用4個進程,每個執行2個任務後都會被殺死。代碼執行後,你可以看到:

pid: 10899 deal with 1 
pid: 10900 deal with 2 
pid: 10901 deal with 3 
pid: 10899 deal with 5 
pid: 10900 deal with 6 
pid: 10901 deal with 7 
pid: 10902 deal with 4 
pid: 10902 deal with 8 
pid: 10907 deal with 9 
pid: 10907 deal with 10 

過程[10899-10902]被殺害後,他們每個人的執行2個任務,以及新工藝10907將用於執行最後一個。

作爲比較,如果我們用一個更大的maxtasksperchild或默認值(這意味着進程將永遠不會被殺死,是活着的,只要池),如下面的代碼:

if __name__ == '__main__': 
    pool = Pool(processes=4, maxtasksperchild=10) 
    keys = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
    result = pool.map(f, keys) 

結果:

pid: 13352 deal with 1 
pid: 13353 deal with 2 
pid: 13352 deal with 4 
pid: 13354 deal with 3 
pid: 13353 deal with 6 
pid: 13352 deal with 7 
pid: 13355 deal with 5 
pid: 13354 deal with 8 
pid: 13353 deal with 9 
pid: 13355 deal with 10 

正如您所看到的,沒有創建新的進程,並且所有任務都使用原來的4個進程完成。

願望這個有用〜

+0

是的,謝謝。我只是想確保(也來自@ DanD。的評論)任務排隊,等待一個自由的過程來接收它們。只有「進程」數量的這些進程仍然存在。 (?° – WoJ

+0

我不確定源代碼,但我猜測任務在像multiprocessing.Queue這樣的結構中排隊,它是一個多生產者 - 消費者模式,所以隊列應該在多進程之間共享。只要池管理他們〜 – linpingta