多线程之Condition
多线程之Condition
我们这说Condition,多线程编程中使用Condition对象代替lock, 能够实现在某个事件触发后才处理数据。
Condition版的生产者与消费者模式:
Lock版本的生产者与消费者模式可以正常的运行。但是存在一个不足,在消费者中,总是通过while True死循环并且上锁的方式去判断钱够不够。上锁是一个很耗费CPU资源的行为。
因此这种方式不是最好的。还有一种更好的方式便是使用threading.condition 来实现。threading.Condition 可以在没有数据的时候处于阻塞等待状态。一旦有合适的数据了,还可以使用notify相关的函数来通知其他处于等待状态的线程。
这样就可以不用做一些无用的上锁和解锁的操作。可以提高程序的性能。首先对threading.Condition 相关的函数做个介绍,threading.Condition 类侧threading.Lock,可以在修改全局数据的时候进行上锁,也可以在修改完毕后进行解锁。
以下将一些常用的函数做个简单的介绍:
1.acquire:上锁。
2.release:解锁。
3.wait:将当前线程处于等待状态,并且会释放锁。可以被其他线程使用notify和notify_all函数唤醒。被唤醒后会继续等待上锁,上锁后继续执行下面的代码。
4.notify:通知某个正在等待的线程,默认是第1个等待的线程。
5.notify-o11:通知所有正在等待的线程。notify和notify-o11不会释放锁。并且需要在release之前调用。
Condition 版的生产者与消费者模式代码如下:
import threading import random import time gMoney=1000 gCondition = threading.Condition() #等同于threading.Lock gTimes = 0 gTotalTimes = 5 class Producer(threading.Thread): def run(self): global gMoney global gCondition global gTimes while True: money=random.randint(100,1000) gCondition.acquire() #加锁(全局变量改变前(gMoney)) if gTimes>=gTotalTimes: gCondition.release() #解锁 print("当前生产者总共生产了%s次" %gTimes) break gMoney += money print("%s当前存入%s元钱,剩余%s元线" %(threading.current_thread(),money,gMoney)) gTimes+=1 gCondition.notify_all() #通知正在等待的线程(wait) gCondition.release() time.sleep(0.5) class Cosumer(threading.Thread): def run(self): global gMoney while True: money = random.randint(100,1000) gCondition.acquire() while gMoney < money: if gTimes >= gTotalTimes: gCondition.release() return print("%s准备消费%d元钱,剩余%d元钱,不足" %(threading.current_thread(),money,gMoney)) gCondition.wait() #等待状态 (获取锁) 直到生产者把钱加上 (有钱了再去排队消费) gMoney -= money print("%s消费了%d元钱,剩余%d元钱" %(threading.current_thread(),money,gMoney)) gCondition.release() time.sleep(0.5) def main(): for x in range(3): t = Cosumer(name="消费者线程%s" %x) t.start() for y in range(5): t1 = Producer(name="生产者线程%s" %y) t1.start() if __name__ == '__main__': main()