2016-03-02 65 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

相关问题