• Condition条件变量


    条件变量是一种比较复杂的线程同步机制

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    
    """
    条件变量,线程间通信提供的另一种锁,用于复杂的线程同步锁。
    
    A先说话,B回答,也就是你一句我一句这种形式,你使用单纯的线程无法实现,就需要使用condition,Condition其实本质还是使用Rlock,当然你可以指定使用Lock,
    实现的关键是Contition的wati和notify这两个函数。
    """
    
    import threading
    from threading import Condition
    
    
    class A(threading.Thread):
        def __init__(self, condition, num):
            self.condition = condition
            self.num = num
            super().__init__(name="A")
    
        def run(self):
            with self.condition:
                for i in range(self.num):
                    print("A say: %s + %s 等于多少 ?" % (str(i), str(i)))
                    self.condition.notify()
                    self.condition.wait()
    
    
    class B(threading.Thread):
        def __init__(self, condition, num):
            self.condition = condition
            self.num = num
            super().__init__(name="B")
    
        def run(self):
            self.condition.acquire() # 必须先获得锁才可以调用wait或者notify
            # with self.condition:  # 这里没有使用with,其实如果不使用with你就手动加锁,然后释放。使用with就帮你自动完成,这就和 with open()自动关闭文件流式一样的。
            for i in range(self.num):
                self.condition.wait()
                print("B say: %s + %s 等于 %s." % (str(i), str(i), str(i+i)))
                self.condition.notify()
            self.condition.release()
    
    if __name__ == '__main__':
        condition = Condition()
        a = A(condition, 5)
        b = B(condition, 5)
    
        """
        这里要注意,虽然是a先说话,但是要先启动b,使用了condition的话线程的启动顺序很重要。如果先启动a,那么就会一直卡住。为什么?
        先启动a,那么就会先执行notify,而b还没有启动也就意味着没有wait,所以卡住了,也就是说notify的前提是先有wait才可以。换句话
        说就是你要通知就得先有人在等,在没人等的情况下你通知了这样你就无法获得回复所以就一直卡在那里。所以先启动b就是先等待,然后启动a
        a说完话就通知,这样b可以收到然后处理,然后b回复,之后唤醒a,这样相继执行。
        其实Condition和event是类似的可以理解为基于事件的通知机制。
    
        注意事项: 1. 先调用 with self.condition 或者是 acquire() 也就是先加锁才可以使用wait和notify
                 2. 如果手动加锁之后要手动释放
                 3. 线程启动顺序很重要
        """
        b.start()
        a.start()
    

  • 相关阅读:
    《TD项目开发小结》
    感悟
    毕业两年了
    ip+port无法访问nginx问题
    问题解决之道
    调休9天的那些日子
    关于类加载器(ClassLoader)
    ios核心蓝牙之心率监控(swift)
    git(git-flow)的高效管理使用
    WKWebview加载本地图片时出现路径问题
  • 原文地址:https://www.cnblogs.com/rexcheny/p/10092319.html
Copyright © 2020-2023  润新知