Python-条件变量锁

Python-条件变量锁

Python条件变量锁

主要说明wait内部基本思想。

一个使用例子

🍉🍉 通过条件变量可以实现线程轮换机制,以下代码来自互联网

Python 复制代码
import threading
import time

num = 0
cv = threading.Condition()


class Alter(threading.Thread):

    def __init__(self, name, action):
        super().__init__()
        self.name = name
        self.action = action

    def run(self):
        global num
        with cv:
            print(f'开始执行{self.name}...')
            while True:
                if self.action == "add":
                    num += 1
                elif self.action == 'reduce':
                    num -= 1
                else:
                    exit(1)
                time.sleep(0.2)
                print(f'num当前为:{num}')
                if num == 5 or num == 0:
                    print(f'停执行{self.name}!')
                    cv.notify()
                    cv.wait()
                    print(f'开始执行{self.name}-{self.ident}')


if __name__ == '__main__':
    a = Alter("加法线程", 'add')
    b = Alter("减法线程", 'reduce')
    a.start()
    b.start()

wait方法内部实现

Python 复制代码
    def wait(self, timeout=None):
        """Wait until notified or until a timeout occurs.

        If the calling thread has not acquired the lock when this method is
        called, a RuntimeError is raised.

        This method releases the underlying lock, and then blocks until it is
        awakened by a notify() or notify_all() call for the same condition
        variable in another thread, or until the optional timeout occurs. Once
        awakened or timed out, it re-acquires the lock and returns.

        When the timeout argument is present and not None, it should be a
        floating point number specifying a timeout for the operation in seconds
        (or fractions thereof).

        When the underlying lock is an RLock, it is not released using its
        release() method, since this may not actually unlock the lock when it
        was acquired multiple times recursively. Instead, an internal interface
        of the RLock class is used, which really unlocks it even when it has
        been recursively acquired several times. Another internal interface is
        then used to restore the recursion level when the lock is reacquired.

        """
        if not self._is_owned():
            raise RuntimeError("cannot wait on un-acquired lock")
        waiter = _allocate_lock()
        waiter.acquire()
        self._waiters.append(waiter)
        saved_state = self._release_save()
        gotit = False
        
        # 通过两次acquire 自我挂起,阻塞自身,直到被通知。
        # timeout本意为阻塞时间
        # gotit 代表通行牌照,直接使用wait() 是因为默认是阻塞行为,一定返回true,但如果设置了阻塞时间,能否获得通行牌照,其之后的逻辑要自己实现。

        try:    # restore state no matter what (e.g., KeyboardInterrupt)
            if timeout is None:
                waiter.acquire()
                gotit = True
            else:
                if timeout > 0:
                    gotit = waiter.acquire(True, timeout)
                else:
                    gotit = waiter.acquire(False)
            return gotit
        finally:
            self._acquire_restore(saved_state)          # 如果获得了排队号码 就能执行wait 之后的 逻辑。
            if not gotit:
                try:
                    self._waiters.remove(waiter)        # 没有通行牌照要在队列中删除锁对象,正常的逻辑在notify中删除。
                except ValueError:
                    pass
  1. underlying lock : 底部锁,优先锁各种翻译,业务上是模型边界锁(内部程序实现就是互斥锁),如果自己提供,可以对其它线程协同。如果不提供它自己默认创建一个RLock。
  2. 说一个模型来描述它的实现原理:阿乐去银行取钱,取钱就是一段行为逻辑,要取钱就要先拿排队号,排队号是取钱逻辑的边界,也就是underlying lock 边界锁,有了排队号,阿乐要取30万,银行柜员没权利,她要等行长签字,这个时候阿乐就要自我挂起,找个地方休息等待行长签字,但正常取钱流程不能停,阿乐要放弃这次取号让其他人先完成业务。等通知可以取30万,阿乐重新取号进入取钱流程即可。
相关推荐
夏沫mds1 分钟前
基于 Flask 与Vue 3 及协同过滤算法的智能电影推荐系统
vue.js·python·flask·协同过滤
sheji34164 分钟前
【开题答辩全过程】以 基于Java的智慧党建管理系统的设计与实现为例,包含答辩的问题和答案
java·开发语言
子午7 分钟前
【2026原创】鱼类识别系统~Python+深度学习+CNN卷积神经网络算法+模型训练+图像识别
图像处理·python·深度学习·cnn
地理探险家7 分钟前
【YOLOv8实战】15组衣物类深度学习数据集分享|附加载+标签管理代码
人工智能·python·深度学习·yolo·模型训练·电商视觉
zh_xuan7 分钟前
kotlin数据类用法
开发语言·kotlin
大学生毕业题目9 分钟前
毕业项目推荐:103-基于yolov8/yolov5/yolo11的皮肤癌检测识别系统(Python+卷积神经网络)
人工智能·python·yolo·目标检测·cnn·pyqt·皮肤癌检测
ai_top_trends9 分钟前
AI 生成 PPT 哪个好用?2026 年主流工具实测对比
人工智能·python
LawrenceLan9 分钟前
17.Flutter 零基础入门(十七):StatelessWidget 与 State 的第一次分离
开发语言·前端·flutter·dart
于初见月11 分钟前
Conda环境中的pip究竟指向哪里?
python·conda·pip
烤麻辣烫11 分钟前
java进阶--刷题与详解-1
java·开发语言·学习·intellij-idea