python27-条件同步变量
2019-06-01 本文已影响0人
筱媛媛
上一篇文章讲述的互斥锁是简单的线程同步机制,但对于复杂线程同步问题的支持无法很好的满足。因此本篇文章引入条件同步变量。Condition除了能提供RLock()和Lock()的方法外,还提供了 wait()、notify()、notifyAll()方法。希望感兴趣的小伙伴可以坚持看下去同时欢迎提出宝贵的意见让我们一起进步!
01:条件同步变量(Condition)
1)概述:在满足了特定的条件后,线程才可以访问相关的数据。
2)原理:线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则wait ; 如果条件满足,进行一些处理改变条件后通过notify方法通知其他线程 ; 其他处于wait状态线程接到通知后会重新判断条件
3)调用方式:cond =threading.Condition(Lock/RLock);不传默认RLock
4)常用方法:
①wait(timeout):线程挂起,等待直到收到一个notify通知或出现超时才会被唤醒继续运行。
②notify(n):唤醒一个或多个等待此条件变量的线程。
③notifyAll():唤醒所有等待此条件的线程。
5)使用场景:生产者与消费者问题,一个线程生产的数据提供给另外一个线程使用。
6)注意事项:
①wait()、notify()、notifyAll()方法必须在已获得Lock前提下才能调用,否则会触发RuntimeError。
②调用wait()会释放Lock,直至该线程被Notify()、NotifyAll()或者超时线程又重新获得Lock。
③如果存在多个线程等待同一个条件,notify()操作会唤醒他们中的一个或多个(这种行为取决于底层的操作系统)
④notify()不会主动释放Lock
02:案例操作
早点铺的师傅必须蒸好包子,消费者才能把包子买来吃掉。即:
生产者可以不断生产商品直到仓库装满然后告知消费者消费;
消费者也可以判断仓库是否满从而告知生产者继续生产商品。
import threading,time,random
lock_con=threading.Condition()#条件锁对象
num_list=[]#创建一个空列表
def producer():
global num_list#引用全局变量
while True:#模拟不停的生产包子
if lock_con.acquire():#上锁
num_list.append(1)
print('生产者:','生产了一个包子',num_list)
lock_con.notifyAll()#通知等待池激活所有线程
lock_con.release()#解锁
time.sleep(random.randint(0,10)*0.1)#模拟包子端上桌的时间
def consumer():
global num_list
while True:#模拟不停的吃掉包子
if lock_con.acquire():#上锁
if len(num_list)==0:
print('包子已卖完,请等待包子生产中!!!')
lock_con.wait()#线程释放锁进入等待,被唤起重新加锁
num_list.remove(num_list[0])#去掉第一个元素
print('消费者:','吃掉了一个包子',num_list)
time.sleep(random.randint(0,10)*0.2)#模拟吃掉包子的时间
lock_con.notifyAll()
lock_con.release()#解锁
t1=threading.Thread(target=producer)
t2=threading.Thread(target=consumer)
t1.start()
t2.start()
t1.join()
t2.join()