2011-03-30 29 views
3

我有一個python程序,從輸入文件中讀取一行,做一些操作並將其寫入輸出文件。我有一臺quadcore機器,我想利用它們全部。我認爲有兩個備選方案要做到這一點,並行我的python程序

  1. 創建N個多蟒蛇處理每個處理的記錄總數/ N
  2. 在一個Python進程創建N個線程,每個輸入記錄,每個線程處理記錄。
  3. 在單個python進程中創建n個線程池,每個線程執行一個輸入記錄。

我從來沒有使用python mutliprocessing功能,請問黑客請問哪種方法是最好的選擇?

回答

4

Python解釋器(CPython)的參考實現包含臭名昭着的"Global Interpreter Lock" (GIL),它一次只允許一個線程執行Python代碼。因此,Python中的多線程非常有限 - 除非您的繁重工作在C語言擴展中完成,而這些擴展釋放了GIL。

克服此限制的最簡單方法是改用multiprocessing模塊。它有一個類似於threading的API,非常簡單易用。在你的情況,你可以使用它像這樣(假設爲操作是困難的部分):

import multiprocessing 

def process_line(line): 
    # This function is executed in your worker processes. Manipulate the 
    # line and return the results. 
    return manipulate(line) 

if __name__ == '__main__': 
    with open('input.txt') as fin, open('output.txt', 'w') as fout: 
     # This creates a pool of N worker processes, where N is the number 
     # of CPUs in your machine. 
     pool = multiprocessing.Pool() 

     # Let the workers do the manipulation and write the results to 
     # the output file: 
     for manipulated_line in pool.imap(process_line, fin): 
      fout.write(manipulated_line) 
+1

由於上下文切換,進程之間的調度,因此,與多線程相比,不是多處理開銷。謝謝。 – Boolean 2011-03-30 07:51:54

+0

是的,但在Python中您不會以任何其他方式獲得任何真正的並行化。 – 2011-03-30 07:54:47

+2

由於上下文切換和調度沒有任何開銷,所以您根本無法並行化,沒關係GIL – slezica 2011-03-30 07:57:07

0

從多個進程讀取同一個文件同時是棘手的。事先可以分割文件嗎?

雖然Python有GIL,但Jython和IronPython都沒有這個限制。

還要確保簡單的單個進程不會使磁盤I/O達到最大值。如果確實如此,你將很難獲得任何東西。

+0

我很驚訝,爲什麼不建議使用多線程選項,因爲多處理有明顯的性能開銷和編譯代碼(分裂)等。 – Boolean 2011-03-30 07:56:52

+0

@Bala:這是Python解釋器的細節,請閱讀http://wiki.python.org/moin/GlobalInterpreterLock。 – 2011-03-30 08:03:26

0

第一個是正確的答案。

首先,創建和管理多個進程比多個線程更容易。您可以使用multiprocessing模塊或類似pyro來處理細節。其次,線程需要處理Python的全局解釋器鎖,即使你是使用Java或C#進行線程處理的專家,它也會使其更加複雜。而最重要的是,多核機器的性能比你想象的更難預測。如果你沒有實現和測量兩種不同的方式去做事情,那麼你直覺哪種方式最快,可能是錯誤的。順便說一下,如果你真的是Java或C#線程專家,那麼你可能應該使用線程代替,但使用JythonIronPython而不是CPython。