2011-12-01 84 views
1

我面臨着類似的問題:如何確保共享變量是線程安全的?

DemoVar = 100 #### or whatever 

def DemoMultiThreadMethod(mode): 
    DemoRLock.acquire() 

    DemoVar = 0 #### or random value 
    ... 
    Other resources which do not support multi-threaded access 

    if mode == 0: 
     do A with DemoVar 

    elif mode == 1: 
     do B with DemoVar 
    ... 

    DemoRLock.release() 

... 

def DecideAfterDemo(self): 
    NewThread = threading.Thread(target = DemoMultiThreadMethod, args = (RandomMode,)) 
    NewThread.start() 

    NewThread.join() 

    Result = DemoVar 

    if Result == SpecificValue: 
     Do something 
    else: 
     Do another 
    ... 

... 

def SpawnThreads(self): 
    #### hundreds of DecideAfterDemo running 
    Counter = 0 

    while Counter < 1000: 
     SpawnAThread = threading.Thread(target = DecideAfterDemo, args =()) 
     SpawnAThread.Start() 

... 

我怎樣才能確保它的安全運行Result = DemoVar

我的意思是,如果有萬噸鎖定DemoMultiThreadMethod s表示正在等待被處理的,你真的不知道其中DemoVar = 0 #### or random value一個Result = DemoVar將首先運行,因爲他們兩人都是原子操作(糾正我,如果我錯誤),這意味着Result = DemoVar可能不安全,如果池中有太多的線程。我能想到的解決方案是在DemoRLock.acquire()之後添加time.sleep(0.01)以確保Result = DemoVar先運行,但這會損失一些生產力。有什麼更好的想法

+1

我在理解您的設置時遇到問題。例如,如果我有一個運行'DecideAfterDemo'方法100次的for循環,它們不會因'NewThread.join()'而並行運行。如果你有一些並行運行線程的替代方法,你是否可以給你的代碼呢? – jsalonen

+0

@jsalonen:在'SpawnThreads'中''DecideAfterDemo'作爲線程運行,但由於'NewThread.join()'在某些時候很多'DecideAfterDemo'會像並行運行 – Shane

+0

感謝您的編輯。現在更有意義。 – jsalonen

回答

1

你想要的是從DemoMultiThreadMethod發送一些值(DemoVar)給DecideAfterDemo。雖然你可以使用一些消息傳遞庫,最簡單的方法是定義線程類......像這樣(未經):每次

class DemoMultiThread(threading.Thread): 
    def __init__(self, mode): 
     self.mode = mode 
     threading.Thread.__init__(self) 
    def run(run): 
     mode = self.mode 
     DemoRLock.acquire() 
     ... 
     self.result = DemoVar 
     DemoRLock.release() 

def DecideAfterDemo(self): 
    NewThread = DemoMultiThread(mode) 
    NewThread.start() 
    NewThread.join() 
    Result = NewThread.result 
    .... 
0

現在,當我嘗試交換多線程/共享信息,我馬上去Queue模塊,這樣比較方便。