互斥锁是最简单的线程同步机制,Python提供的Condition对象提供了对复杂线程同步问题的支持。Condition被称为条件变量,除了提供与Lock相似的acquire和release方法外,还提供了wait和notify方法。线程首先acquire一个条件变量,而后判断一些条件。若是条件不知足则wait;若是条件知足,进行一些处理改变条件后,经过notify方法通知其余线程,其余处于wait状态的线程接到通知后会从新判断条件。不断的重复这一过程,从而解决复杂的同步问题。 html
能够认为Condition对象维护了一个锁(Lock/RLock)和一个waiting池。线程经过acquire得到Condition对象,当调用wait方法时,线程会释放Condition内部的锁并进入blocked状态,同时在waiting池中记录这个线程。当调用notify方法时,Condition对象会从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁。 python
Condition对象的构造函数能够接受一个Lock/RLock对象做为参数,若是没有指定,则Condition对象会在内部自行建立一个RLock。 函数
除了notify方法外,Condition对象还提供了notifyAll方法,能够通知waiting池中的全部线程尝试acquire内部锁。因为上述机制,处于waiting状态的线程只能经过notify方法唤醒,因此notifyAll的做用在于防止有线程永远处于沉默状态。 ui
演示条件变量同步的经典问题是生产者与消费者问题:假设有一群生产者(Producer)和一群消费者(Consumer)经过一个市场来交互产品。生产者的”策略“是若是市场上剩余的产品少于1000个,那么就生产100个产品放到市场上;而消费者的”策略“是若是市场上剩余产品的数量多余100个,那么就消费3个产品。用Condition解决生产者与消费者问题的代码以下: 线程
import threading code
import time class Producer(threading.Thread): def run(self): global count while True: if con.acquire(): if count > 1000: con.wait() else: count = count+100 msg = self.name+' produce 100, count=' + str(count) print msg con.notify() con.release() time.sleep(1) class Consumer(threading.Thread): def run(self): global count while True: if con.acquire(): if count < 100: con.wait() else: count = count-3 msg = self.name+' consume 3, count='+str(count) print msg con.notify() con.release() time.sleep(1) count = 500 con = threading.Condition() def test(): for i in range(2): p = Producer() p.start() for i in range(5): c = Consumer() c.start() if __name__ == '__main__': test()