0

我有了解的一些問題我在下面的代碼我寫的其他一些劇本我寫去認真處理多的簡化回事過程:如何在遞歸多處理函數中處理最大進程數的操作系統限制?

import multiprocessing 
import time 
from random import randint 
from os import getpid 



def f(i, process_id, parent_process_message_queue): 

    print (i,process_id, getpid()) 
    time.sleep(randint(0,10)/100) 

    child_processes = [] 
    child_process_message_queue = multiprocessing.Queue() 

    if randint(0,10) > 4: 
     child_processes.append(multiprocessing.Process(target = f, args = (i+1, 0, child_process_message_queue))) 
     child_processes[-1].start() 
     child_processes.append(multiprocessing.Process(target = f, args = (i+1, 1, child_process_message_queue))) 
     child_processes[-1].start() 

    while not child_process_message_queue.empty(): 
     child_id = child_process_message_queue.get() 
     child_processes[child_id].join() 
    parent_process_message_queue.put(process_id) 


child_process_message_queue = multiprocessing.Queue() 

p = multiprocessing.Process(target = f, args = (0, 0, child_process_message_queue)) 
p.start() 

while not child_process_message_queue.empty(): 
    child_id = child_process_message_queue.get() 
    child_processes[child_id].join() 

p.join() 

當沒有太多的遞歸調用發生(因爲隨機元素),那麼這段代碼似乎按預期工作。一個成功運行的

輸出看起來是這樣的:

0 0 57756 
1 0 57757 
1 1 57758 
2 0 57759 
2 1 57760 
3 0 57761 
3 1 57762 
3 0 57763 
3 1 57764 
4 0 57765 
4 1 57766 
4 0 57767 
4 1 57768 
5 0 57769 
5 1 57770 

然而,當正在犯了太多的遞歸調用,事情變得陌生;這樣的事情出現,其中包括一些錯誤消息:

Process Process-1:2:1:2:1:2:2:2:2:1:1:1:1:1:1:1:1:2:2:2:2:2:2:1:1:1:2:2:1:1:1:1:2:1:2:1: 
Process Process-1:2:1:2:1:2:2:2:2:1:1:1:1:1:1:1:2:2:2:1:2:2:2:1:2:2:2:1:2:2:2:1:1:2:2:2:1:1:1:1:2: 
Process Process-1:2:1:2:1:2:2:2:2:1:1:1:1:1:1:1:1:2:2:2:2:2:2:2:2:2:2:2:2:2:1:2:2:2:1:2:2:2:1:2: 
Process Process-1:2:1:2:1:2:2:2:2:1:1:1:1:1:1:1:1:2:2:2:1:2:2:2:1:2:1:2:2:1:1:2:2:1:2:2:1:2:1:1:2:1:1: 
Process Process-1:2:1:2:2:2:2:1:2:2:2:1:1:1:2:1:2:2:1:2:2:1:1:2:1:1:1:2:1:1:2:2:1:1:1:1:1:1:1:1:2:1:1:2:2:2:2:2: 
Traceback (most recent call last): 
    File "/Users/user/anaconda/lib/python3.6/multiprocessing/process.py", line 249, in _bootstrap 
    self.run() 
    File "/Users/user/anaconda/lib/python3.6/multiprocessing/process.py", line 93, in run 
    self._target(*self._args, **self._kwargs) 
    File "queuetest2.py", line 18, in f 
    child_processes[-1].start() 
    File "/Users/user/anaconda/lib/python3.6/multiprocessing/process.py", line 105, in start 
[...] 
    Traceback (most recent call last): 
    BlockingIOError: [Errno 35] Resource temporarily unavailable 

我中搜索的結果錯誤(BlockingIOError:[錯誤35]),顯然此行爲是由所述憑證試圖創建多個進程大於允許由OS引起的。現在我想知道:處理這個問題的最佳方法是什麼?我不認爲使用多處理的遞歸函數本身是一個壞主意,是嗎?解決方案可能需要檢查是否已達到流程上限,如果是這樣,則繼續在同一線程中遞歸,如果不是,則繼續產生新流程,但這是否是一種合理的方法?

回答

1

即使遞歸調用的次數很少,您的方法對性能也是非常不利的。

通常,在CPU綁定類型的作業上,最好保持過程/ CPU比率爲1.對於IO界限而言,線程是更好的方法。對於混合作業,它會變得更加複雜一些,只有測試工作量才能給出具體的答案。

獨立於工作負載,開發人員總是希望控制應用程序要創建的進程/線程的數量。爲了達到這個目的,最簡單的設計模式是使用Pool of Workers

Python庫提供了兩種不同的實現:multiprocessing.Poolconcurrent.futures.Executor

相關問題