2009-10-19 63 views
10

我編寫了以下代碼,以使我的第二個CPU內核工作。代碼的基本功能是首先在目錄層次結構中查找所需的「海洋」文件,然後執行一組外部腳本來處理這些二進制「海洋」文件,從而生成數量爲50到100的文本和二進制文件。正如問題的標題所提示的,以提高處理速度的並行方式。使用工作人員的多處理池

這個問題來源於我們在IPython用戶名單上以「Cannot start ipcluster」爲名的長篇討論。從我對IPython並行處理功能的實驗開始。

問題是我不能讓這段代碼正確運行。如果包含「海」文件的文件夾僅包含「海」文件,腳本將在未完全執行外部腳本運行的情況下完成其執行。 (假設我有30-50個外部腳本可以運行,但是隻有在執行這些外部腳本鏈中的第一個腳本後,我的啓用多處理的腳本纔會耗盡。)有趣的是,如果我在已處理的文件夾(即「海」預處理和輸出文件已經在該文件夾中),然後運行,但是這次我得到的線性處理時間約2.4到2.7倍的加速。這是不是很期待,因爲我的筆記本電腦只有一個Core 2 Duo 2.5 Ghz CPU。雖然我有一個CUDA驅動的GPU,但它與我目前的並行計算鬥爭無關:)

您認爲這可能是這個問題的根源嗎?

謝謝你的所有意見和建議。

#!/usr/bin/env python 

from multiprocessing import Pool 
from subprocess import call 
import os 


def find_sea_files(): 

    file_list, path_list = [], [] 
    init = os.getcwd() 

    for root, dirs, files in os.walk('.'): 
     dirs.sort() 
     for file in files: 
      if file.endswith('.sea'): 
       file_list.append(file) 
       os.chdir(root) 
       path_list.append(os.getcwd()) 
       os.chdir(init) 

    return file_list, path_list 


def process_all(pf): 
    os.chdir(pf[0]) 
    call(['postprocessing_saudi', pf[1]]) 


if __name__ == '__main__': 
    pool = Pool(processes=2)    # start 2 worker processes 
    files, paths = find_sea_files() 
    pathfile = [[paths[i],files[i]] for i in range(len(files))] 
    pool.map(process_all, pathfile) 
+0

與其說頂部外部腳本,當我嘗試調用子腳本是postprocessing_saudi的一部分,即process_raw和執行我得到一個神祕的錯誤: 以下僅僅是一個錯誤的一部分。如圖所示,IDL執行困惑,無法獲得正確的結果。 [gsever @ ccn partest] $ python proall3.py PID:17722 PID:17723 IDL版本7.1(linux x86 m32)。 (c)2009年,ITT視覺信息解決方案 IDL版本7.1(linux x86 m32)。 (c)2009年,ITT視覺信息解決方案 %無法獲取文件狀態。單位:0,文件: 錯誤的文件描述符 – 2009-12-26 00:44:39

回答

6

我會開始得到一個更好的感覺,對於正在發生的事情與工作進程。如果需要,多處理模塊會爲其子流程進行日誌記錄。既然你已經簡化了代碼,以縮小問題,我只想用幾個打印語句調試,像這樣(或者你可以PrettyPrint的PF陣列):


def process_all(pf): 
    print "PID: ", os.getpid() 
    print "Script Dir: ", pf[0] 
    print "Script: ", pf[1] 
    os.chdir(pf[0]) 
    call(['postprocessing_saudi', pf[1]]) 


if __name__ == '__main__': 
    pool = Pool(processes=2) 
    files, paths = find_sea_files() 
    pathfile = [[paths[i],files[i]] for i in range(len(files))] 
    pool.map(process_all, pathfile, 1) # Ensure the chunk size is 1 
    pool.close() 
    pool.join() 

的Python的版本,我有用2.6.4完成了。

+0

該腳本訪問第一個目錄,並且無需啓動外部處理過程,該腳本將轉到第二個目錄並嘗試處理其中的第一個文件 [gsever @ ccn partest] $ python proall3.py PID:10723 腳本導演:/家庭/ gsever /桌面/ partest/20090317_131342 /後 腳本:09_03_17_13_13_42.sea PID:10724 腳本導演:/家庭/ gsever /桌面/ partest/20090318_075533 /後 腳本:09_03_18_07_55_33.sea 處理的09_03_18_07_55_33 .sea文件.......................處理09_03_17_13_13_42.sea文件.................. .....完成 – 2009-12-25 17:26:44

+0

再次執行失敗,甚至沒有正確應用外部腳本ch在每個海上的文件。我仍然認爲這個問題與Python的多處理模塊有關。我很樂意聽到更多的意見來找出確切的問題。 – 2009-12-25 17:31:25

3

有幾件事我能想到的:

1)你有沒有印出來的pathfiles?你確定它們都是正確生成的嗎?

a)我問你的os.walk有點有趣; dirs.sort()應該沒問題,但看起來很不自然。一般不應該使用os.chdir();恢復應該是好的,但一般來說,你應該只是追加到init。

2)我見過python2.6上的多處理有問題從池中產生subporcesses。 (我特意有一個腳本使用多處理來產生子進程,然後這些子進程無法正確使用多處理(池被鎖定))。試試python2.5 w /多處理backport。

3)嘗試picloud的cloud.mp模塊(包裝多處理,但處理池有點不同),看看是否有效。

你會做

cloud.mp.join(cloud.mp.map(process_all, pathfile)) 

(聲明:我是PiCloud的開發者之一)

+0

1)是的,路徑都是正確的。我使用IPython的並行處理功能測試相同的路徑,主腳本通過文件夾並執行正確鏈接腳本以完全後處理海洋文件。 a)sort()是我的Fedora文件系統(ext4)的解決方法。沒有它os.walk()任意訪問文件夾。 2)我會看看2.5。現在我用2.6.0 3)謝謝你的建議。我會試一試,但是我傾向於不爲其他人添加外部要求來輕鬆執行腳本。 – 2009-12-25 17:20:13