2012-11-12 83 views
0

我有一個應用程序,在給定的intervall循環通過項目列表(然後這個列表的長度變化)爲每個項目它做了一個相當簡單的操作,它不只是增加一個值,但不是這是一些非常複雜的計算。需要多少鎖和

什麼我不知道是我應該鎖定爲這樣的(目前的解決方案)的每個項目:

def method_1: 
    for item in the_list: 
     do_operation(item); 

def do_operation(item): 
    lock() 
    //do some stuff. 
    unlock() 

或者我應該做這樣的:

def method_1: 
    lock() 
    for item in the_list: 
     do_operation(item); 
    unlock() 

def do_operation(item): 
    //do some stuff. 

我想這其實是真的很難回答,因爲我認爲這很大程度上取決於「做一些事情」是什麼以及需要多長時間。我真的不知道這需要多少時間。特別是與蟒蛇獲得鎖定需要多長時間相比。

讓我知道在評論中是否可以改進我的問題。

+1

有往往是開銷相對高量。因此,我傾向於爭取後一種選擇。特別是在這種情況下,沒有實質性的循環部分不會成爲關鍵部分的一部分。另一方面,如果'do_operation'在其他地方使用,並且應該始終受到保護,那麼在函數內部執行鎖定是有意義的。 – jpm

+0

如果你不使用線程,那麼沒有,沒有必要。在你的代碼中注意你需要使用它。 –

+0

許多鎖支持上下文管理器協議('帶鎖:做東西')。這對於異常情況很有幫助(另一種方法是'try:'/'finally:'子句)。 – glglgl

回答

0

我建議鎖定整個列表(選項2)。如果您只鎖定每個項目,則可能會在操作過程中對列表進行部分修改,這可能存在問題,具體取決於您所做的操作。每個鎖定和解鎖也有開銷。

+0

有關列表變更的好處。 –

+0

它取決於你是否改變列表本身,主要是長度或順序,或者如果你只是改變其中的元素。如果你想操縱列表,你應該看看隊列模塊。更常見的情況是,您不希望多個線程操縱列表/隊列的成員,因爲這是併發中的基本生產者/消費者範式。 –

1

您通常希望保持鎖的時間片儘可能短。所以你會正常地在變量訪問之前立即鎖定並立即將其放下。你不想阻塞一個完整的循環,因爲它破壞了併發的主要原因。

在列表的情況下:您是否研究了特別針對線程執行的不同Queue-classes

而jpm的評論是正確的。如果你的其他線程也做了一些東西,你也希望它們受到保護。甚至可能有線程匱乏的問題。

0

如果鎖只是爲了保護列表(而不是項目本身),你也可以做

def method_1: 
    lock() 
    list = the_list[:] 
    unlock() 
    for item in list: 
     do_operation(item);