2013-12-09 93 views
0

所以我有兩個python腳本。第一個是掃描數千個文件的解析器,第二個是一個調度器,用於掃描數百個獨立的目錄。我的問題是這樣的:Python:多進程池中的強制num進程

我有有限的磁盤資源量,每次掃描使用大約1GB的本地sqlite3存儲。我需要限制進程的數量,以便在進程的最大數量運行時,我不會得到磁盤IO錯誤,這是我一直在得到的。

我試過使用下面的代碼來分叉掃描並保持進程爲8,但是當我在我的臨時目錄(其中存儲臨時本地文件的地方)中顯示的實際上有超過8個文件顯示我的我沒有正確地限制進程(我使用os.remove在掃描完成後擺脫臨時文件)。

這是我的,僅僅fork了關閉的過程與井格式化命令

def execute_scan(cmd): 
    try: 
     log("Executing "+ str(cmd)) 
     subprocess.call(cmd, shell=False) 
    except Exception as e: 
     log(e) 
     log(cmd) 

這是在我的主要方法,其中getCommand(OBJ)中的對象的數據轉換到命令陣列執行掃描方法。

tasks = [getCommand(obj) for obj in scanQueue if getCommand(obj) is not None] 
multiprocessing.Pool(NUM_PROCS).map(execute_scan, tasks) 

我可以用任何意見,我可以得到,因爲我處理大量的數據和我的硬盤並不大。

非常感謝!

+1

我會再次重複一遍:[並行化I/O綁定任務會導致比在單個線程(或進程)中運行任務更糟的運行時間](http://stackoverflow.com/a/20421535/1595865) 。使用多線程或進程只有在處理CPU綁定任務時纔有用(並且不是每次都是這樣) – goncalopp

+0

您沒有顯示刪除臨時文件的任何代碼,但這可能是問題所在。查看臨時文件以間接推斷有多少進程正在運行是奇怪的;-)使用OS工具直接計算進程的數量。 'Pool(NUM_PROCS)'創建*完全*'NUM_PROCS'進程 - 不多也不少。 –

+0

@TimPeters正如我在描述中提到的那樣,我使用os.remove(path)去除臨時文件,並且該部分工作正常。 – onetwopunch

回答

0

即使我可能已經使用多關於這個應用程序使用一個簡短的教程,事實證明,因爲IO到sqlite3的數據庫是瓶頸,多實際上是減緩下來就像goncalopp預測的一樣。

0

gevent.pool.Pool可能是適合您的解決方案。因爲gevent使用greenlet來執行併發操作,並且一次只能運行一個greenlet。

在你的情況下,首先將池的大小設置爲一個合適的數字,這意味着最多隻有一些greenlet可以做一些I/O操作。然後將執行掃描任務的功能轉換爲greenlet並將其添加到池中,以便由集線器 greenlet調度。

以下是有關的gevent.pool.Pool