2016-03-02 28 views
1

我有這樣的例子代碼來解釋我的問題:如何在運行前啓動兩個線程並鎖定它們,並且只有在解鎖時才執行?

import threading 
import time 

class thread1(threading.Thread): 

    def __init__(self, lock): 
     threading.Thread.__init__(self) 
     self.daemon = True 
     self.start()   
     self.lock = lock 

    def run(self): 
     while True: 
      self.lock.acquire(True) 
      print ('write done by t1') 
      self.lock.release() 

class thread2(threading.Thread): 

    def __init__(self, lock): 
     threading.Thread.__init__(self) 
     self.daemon = True 
     self.start()   
     self.lock = lock 

    def run(self): 
     while True: 
      self.lock.acquire(True) 
      print ('write done by t2') 
      self.lock.release() 

if __name__ == '__main__': 
    lock = threading.Lock() 
    t1 = thread1(lock) 
    t2 = thread2(lock) 

    lock.acquire(True) 

    counter = 0 

    while True: 
     print("main...") 
     counter = counter + 1 
     if(counter==5 or counter==10): 
      lock.release() # Here I want to unlock both threads to run just one time and then wait until I release again 
     time.sleep(1) 

    t1.join() 
    t2.join() 

我遇到一些問題如下:

我想有兩個線程(線程1和線程),它們在推出開始該程序的,但它們應該等到main()counter達到5或10

main()counter達到5或10,但應信號/觸發/解鎖的螺紋,兩者threads應只運行一次,然後等到新的unlock

我期待的代碼具有以下輸出(每行是1秒運行):

main... 
main... 
main... 
main... 
main... 
write done by t1 
write done by t2 
main... 
main... 
main... 
main... 
main... 
write done by t1 
write done by t2 

相反,我有不同的行爲,例如與起始:

write done by t1 
write done by t1 
write done by t1 
write done by t1 

(等)

並經過5秒

write done by t2 

很多次...

有人可以幫我解釋什麼是錯的,我該如何改善這一點?

回答

1
  1. 在線程1和線程的_ _初始化_ _(),啓動()被分配self.lock之前被調用。
  2. t1和t2是在主線程獲取鎖之前創建的。這使得這兩個線程在主線程鎖定它們之前開始打印。這是您的代碼打印前幾行「由x完成寫入」的原因。
  3. 計數器達到5後,主線程釋放該鎖,但不會再次鎖定該鎖。這使得t1和t2繼續運行。
  4. ,除非你殺了它,它決不會退卻...

我建議你使用Condition Object而不是鎖定。

這裏是一個基於你的代碼的例子。

import threading 
import time 


class Thread1(threading.Thread): 
    def __init__(self, condition_obj): 
     super().__init__() 
     self.daemon = True 
     self.condition_obj = condition_obj 
     self.start() 

    def run(self): 
     with self.condition_obj: 
      while True: 
       self.condition_obj.wait() 
       print('write done by t1') 


class Thread2(threading.Thread): 
    def __init__(self, condition_obj): 
     super().__init__() 
     self.daemon = True 
     self.condition_obj = condition_obj 
     self.start() 

    def run(self): 
     with self.condition_obj: 
      while True: 
       self.condition_obj.wait() 
       print('write done by t2') 


if __name__ == '__main__': 
    condition = threading.Condition() 
    t1 = Thread1(condition) 
    t2 = Thread2(condition) 

    counter = 0 

    while True: 
     print("main...") 
     counter += 1 
     if counter == 5 or counter == 10: 
      with condition: 
       condition.notify_all() 
     time.sleep(1) 

    t1.join() 
    t2.join() 
+0

真棒!謝謝你的解釋!! – waas1919

相關問題