多线程之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()

 

 

posted @ 2019-03-14 12:38  cmap  阅读(510)  评论(0编辑  收藏  举报