zoukankan      html  css  js  c++  java
  • 多线程之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()

  • 相关阅读:
    VUE(vue对象的简单属性)
    使用Dockerfile封装Django镜像
    Django路由小知识
    字符编码小知识
    python值的引用传递和go语言的值传递
    centos输入正确的账号和密码登陆不进去
    迅为4412开发平台Zigbee模块在物联网智能家居中的应用
    全新升级4412开发板项目学习实战资料
    迅为4418开发板平台应用于智能门禁系统
    【分享】iTOP-iMX6UL开发板驱动看门狗 watchdog 以及 Linux-c 测试例程
  • 原文地址:https://www.cnblogs.com/c-pyday/p/10529546.html
Copyright © 2011-2022 走看看