python笔记11-多线程之Condition(条件变量)
前言
当小伙伴a在往火锅里面添加鱼丸,这个就是生产者行为;另外一个小伙伴b在吃掉鱼丸就是消费者行为。当火锅里面鱼丸达到一定数量加满后b才能吃,这就是一种条件判断了。
这就是本篇要讲的Condition(条件变量)
一、Condition
Condition(条件变量)通常与一个锁关联。需要在多个Contidion中共享一个锁时,可以传递一个Lock/RLock实例给构造方法,否则它将自己生成一个RLock实例。
可以认为,除了Lock带有的锁定池外,Condition还包含一个等待池,池中的线程处于状态图中的等待阻塞状态,直到另一个线程调用notify()/notifyAll()通知;得到通知后线程进入锁定池等待锁定。
Condition():
- acquire(): 线程锁
- release(): 释放锁
- wait(timeout): 线程挂起,直到收到一个notify通知或者超时(可选的,浮点数,单位是秒s)才会被唤醒继续运行。wait()必须在已获得Lock前提下才能调用,否则会触发RuntimeError。
- notify(n=1): 通知其他线程,那些挂起的线程接到这个通知之后会开始运行,默认是通知一个正等待该condition的线程,最多则唤醒n个等待的线程。notify()必须在已获得Lock前提下才能调用,否则会触发RuntimeError。notify()不会主动释放Lock。
- notifyAll(): 如果wait状态线程比较多,notifyAll的作用就是通知所有线程
二、 生产者与消费者
```
# coding=utf-8
import threading
import time
con = threading.Condition()
num = 0
# 生产者
class Producer(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
# 锁定线程
global num
con.acquire()
while num < 5:
print "开始添加!!!"
num += 1
print "火锅里面鱼丸个数:%s" % str(num)
time.sleep(1)
if num >= 5:
print "火锅里面里面鱼丸数量已经到达5个,无法添加了!"
# 唤醒等待的线程
con.notify() # 唤醒小伙伴开吃啦
# 释放锁
con.release()
# 消费者
class Consumers(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
con.acquire()
global num
while num > 0:
print "开始吃啦!!!"
num -= 1
print "火锅里面剩余鱼丸数量:%s" %str(num)
time.sleep(2)
if num <= 0:
print "锅底没货了,赶紧加鱼丸吧!"
con.wait()
con.release()
a = Producer()
b = Consumers()
a.start()
b.start()
```
运行结果:
开始添加!!!
火锅里面鱼丸个数:1
开始添加!!!
火锅里面鱼丸个数:2
开始添加!!!
火锅里面鱼丸个数:3
开始添加!!!
火锅里面鱼丸个数:4
开始添加!!!
火锅里面鱼丸个数:5
火锅里面里面鱼丸数量已经到达5个,无法添加了!
开始吃啦!!!
火锅里面剩余鱼丸数量:4
开始吃啦!!!
火锅里面剩余鱼丸数量:3
开始吃啦!!!
火锅里面剩余鱼丸数量:2
开始吃啦!!!
火锅里面剩余鱼丸数量:1
开始吃啦!!!
火锅里面剩余鱼丸数量:0
锅底没货了,赶紧加鱼丸吧!