• 详解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()
    

      

  • 相关阅读:
    Python正课101 —— 前端 入门
    Python正课100 —— 数据库 进阶5
    Python正课99 —— 数据库 进阶4
    Navicat15安装教程
    Python正课98 —— 数据库 进阶3
    Python正课97 —— 数据库 进阶2
    Python正课96 —— 数据库 进阶1
    解决:MySQL报错
    Python正课95 —— 数据库 入门
    作业3
  • 原文地址:https://www.cnblogs.com/yoyo1216/p/15740439.html
Copyright © 2020-2023  润新知