2012-05-07 63 views
8

我有一個簡單的Python腳本,它使用了兩個更復雜的Python腳本,並對結果進行了一些操作。非常簡單的Python併發編程

我有兩個模塊,Foo和酒吧,和我的代碼是這樣的:

import Foo 
import Bar 

output = [] 

a = Foo.get_something() 
b = Bar.get_something_else() 

output.append(a) 
output.append(b) 

這兩種方法都需要很長的時間來運行,也不依賴於其他的,所以顯而易見的解決方案是並行運行它們。我該如何做到這一點,但要確保訂單得到保持:無論哪個人先完成,必須等待另一個人完成,然後才能繼續執行

讓我知道如果我沒有讓自己清楚,我試圖讓示例代碼儘可能簡單。

編輯:

感謝琥珀色,您的解決方案可與一個細微的變化。

而是在創建時調用每個線程的start(),我將它們像這樣:

threadname = threading.Thread(target=foo) 
threadname.start() 

如果沒有這個,我得到的錯誤AttributeError: 'NoneType' object has no attribute 'join'和一些非常怪異的行爲與併發。如果你在下面編輯你的答案,我會將其標記爲已解決。

回答

20

一般來說,你會用threading來做到這一點。

首先,創建要並行運行每一件事情線程:

import threading 

import Foo 
import Bar 

results = {} 

def get_a(): 
    results['a'] = Foo.get_something() 
a_thread = threading.Thread(target=get_a) 
a_thread.start() 

def get_b(): 
    results['b'] = Bar.get_something_else() 
b_thread = threading.Thread(target=get_b) 
b_thread.start() 

然後要求他們都已經完成,對兩者使用.join()

a_thread.join() 
b_thread.join() 

處點你的結果將在results['a']results['b'],所以如果你想要一個有序列表:

output = [results['a'], results['b']] 

注:如果這兩個任務本質上是CPU密集型的,你可能要考慮multiprocessing代替 - 由於Python的GIL,給定的Python進程將只使用一個CPU核心,而multiprocessing可以分發任務分離芯。但是,它的開銷略高於threading,因此如果這些任務的CPU密集度較低,則可能效率不高。

+3

線程有助於空閒代碼。如果它有很多繁重的計算,你應該建議多處理,因爲在這種情況下,線程只會增加延遲。 – akaRem

+0

@akaRem當然,我可以在關於這個的一個筆記編輯。 – Amber

+0

是的,它是非常密集的CPU。然而,我會首先得到這個工作。我有一個快速的樣子,API是相同的。 – Rory

7
import multiprocessing 

import Foo 
import Bar 

results = {} 

def get_a(): 
    results['a'] = Foo.get_something() 



def get_b(): 
    results['b'] = Bar.get_something_else() 

process_a = multiprocessing.Process(target=get_a) 
process_b = multiprocessing.Process(target=get_b) 


process_b.start() 
process_a.start() 


process_a.join 
process_b.join 

這是您程序的進程版本。

注意:在線程有共享的數據結構,所以你不必擔心鎖定避免了數據的錯誤操作以及琥珀它上面也有一個GIL(全局解釋器鎖)的問題,因爲這兩個你的任務提到的CPU那麼這意味着需要更多的時間,因爲這些調用會通知線程獲取和釋放的線程。但是,如果你的任務是I/O密集型的,那麼它不會有太大的影響。

現在,由於在一個過程中沒有共享的數據結構,所以不用擔心LOCKS,因爲它不管GIL如何工作,所以您實際上可以享受多處理器的真正力量。

簡單的註記:過程是一樣的線程只是不使用一個共享的數據結構(一切工作孤立,專注於提供消息。)

退房dabeaz.com他介紹了並行編程的好介紹一次。