Python threading模块condition原理及运行流程详解
Condition的处理流程如下:
首先acquire一个条件变量,然后判断一些条件。
- 如果条件不满足则wait;
- 如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。
- 不断的重复这一过程,从而解决复杂的同步问题。
Condition的基本原理如下:
可以认为Condition对象维护了一个锁(Lock/RLock)和一个waiting池。线程通过acquire获得Condition对象,当调用wait方法时,线程会释放Condition内部的锁并进入blocked状态,同时在waiting池中记录这个线程。当调用notify方法时,Condition对象会从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁。
Condition对象的构造函数可以接受一个Lock/RLock对象作为参数,如果没有指定,则Condition对象会在内部自行创建一个RLock。
除了notify方法外,Condition对象还提供了notifyAll方法,可以通知waiting池中的所有线程尝试acquire内部锁。由于上述机制,处于waiting状态的线程只能通过notify方法唤醒,所以notifyAll的作用在于防止有的线程永远处于沉默状态。
演示条件变量同步的经典问题是生产者与消费者问题:假设有一群生产者(Producer)和一群消费者(Consumer)通过一个市场来交互产品。生产者的”策略“是如果市场上剩余的产品少于1000个,那么就生产100个产品放到市场上;而消费者的”策略“是如果市场上剩余产品的数量多余100个,那么就消费3个产品。用Condition解决生产者与消费者问题的代码如下:
#-*-coding:utf-8-*- """ CreatedonWedNov2817:15:292018 @author:18665 """ importthreading importtime classProducer(threading.Thread): #生产者函数 defrun(self): globalcount whileTrue: ifcon.acquire(): #当count小于等于1000的时候进行生产 ifcount>1000: con.wait() else: count=count+100 msg=self.name+'produce100,count='+str(count) print(msg) #完成生成后唤醒waiting状态的线程, #从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁 con.notify() con.release() time.sleep(1) classConsumer(threading.Thread): #消费者函数 defrun(self): globalcount whileTrue: #当count大于等于100的时候进行消费 ifcon.acquire(): ifcount<100: con.wait() else: count=count-5 msg=self.name+'consume5,count='+str(count) print(msg) con.notify() #完成生成后唤醒waiting状态的线程, #从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁 con.release() time.sleep(1) count=500 con=threading.Condition() deftest(): foriinrange(2): p=Producer() p.start() foriinrange(5): c=Consumer() c.start() if__name__=='__main__': test()
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。