zoukankan      html  css  js  c++  java
  • 详解threading模块:Condition类的使用

    Python提供的Condition对象提供了对复杂线程同步问题的支持。

    • Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还提供了wait和notify方法。

    Condition的处理流程如下:

    • 首先acquire一个条件变量,然后判断一些条件。
    • 如果条件不满足则wait;
    • 如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。
    • 不断的重复这一过程,从而解决复杂的同步问题。

    Condition的基本原理如下:

    可以认为Condition对象维护了一个锁(Lock/RLock)和一个waiting池。线程通过acquire获得Condition对象,当调用wait方法时,线程会释放Condition内部的锁并进入blocked状态,同时在waiting池中记录这个线程。当调用notify方法时,Condition对象会从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁。

    Condition对象的构造函数可以接受一个Lock/RLock对象作为参数,如果没有指定,则Condition对象会在内部自行创建一个RLock。

    除了notify方法外,Condition对象还提供了notifyAll方法,可以通知waiting池中的所有线程尝试acquire内部锁。由于上述机制,处于waiting状态的线程只能通过notify方法唤醒,所以notifyAll的作用在于防止有的线程永远处于沉默状态。

    import threading
    from concurrent import futures
    
    
    # 通过condition完成协同读诗
    
    class XiaoAi(threading.Thread):
        def __init__(self, cond):
            super().__init__(name="小爱")
            self.cond = cond
    
        def run(self):
            with self.cond:
                self.cond.wait()
                print("{} : 在 ".format(self.name))
                self.cond.notify()
    
                self.cond.wait()
                print("{} : 好啊 ".format(self.name))
                self.cond.notify()
    
                self.cond.wait()
                print("{} : 君住长江尾 ".format(self.name))
                self.cond.notify()
    
                self.cond.wait()
                print("{} : 共饮长江水 ".format(self.name))
                self.cond.notify()
    
                self.cond.wait()
                print("{} : 此恨何时已 ".format(self.name))
                self.cond.notify()
    
                self.cond.wait()
                print("{} : 定不负相思意 ".format(self.name))
                self.cond.notify()
    
    
    class TianMao(threading.Thread):
        def __init__(self, cond):
            super().__init__(name="天猫精灵")
            self.cond = cond
    
        def run(self):
            with self.cond:
                print("{} : 小爱同学 ".format(self.name))
                self.cond.notify()
                self.cond.wait()
    
                print("{} : 我们来对古诗吧 ".format(self.name))
                self.cond.notify()
                self.cond.wait()
    
                print("{} : 我住长江头 ".format(self.name))
                self.cond.notify()
                self.cond.wait()
    
                print("{} : 日日思君不见君 ".format(self.name))
                self.cond.notify()
                self.cond.wait()
    
                print("{} : 此水几时休 ".format(self.name))
                self.cond.notify()
                self.cond.wait()
    
                print("{} : 只愿君心似我心 ".format(self.name))
                self.cond.notify()
                self.cond.wait()
    
    
    if __name__ == "__main__":
        cond = threading.Condition()
        xiaoai = XiaoAi(cond)
        tianmao = TianMao(cond)
    
        # 启动顺序很重要
        # 在调用with cond之后才能调用wait或者notify方法
        # condition有两层锁, 一把底层锁会在线程调用了wait方法的时候释放, 上面的锁会在每次调用wait的时候分配一把并放入到cond的等待队列中,等到notify方法的唤醒
        xiaoai.start()
        tianmao.start()
    

      

  • 相关阅读:
    C#学习记录二:高级数据存储方式
    SharePoint 2010 匿名用户调用Client Object Model访问列表项
    Android 在闹钟开机时,如何解决开机动画没有播完就进入Launcher M
    Getting in Line UVA 216
    Android 如何关闭Navigation Bar M
    google protocol buffer 简介 版本 安装 使用 实例
    Android [VP]视频播放器播放本地视频时收到短信/彩信,需要界面提示 M
    Maven教程初级篇02:pom.xml配置初步
    当Ruby的model名字出错时,在现实view时显示错误的提示
    VS Code 安装 C++ 调试环境
  • 原文地址:https://www.cnblogs.com/yoyo1216/p/15740439.html
Copyright © 2011-2022 走看看