当前位置: 首页 > news >正文

Python Condition对象wait方法使用与修复

在 Python 中,Condition 对象用于线程同步,其 wait() 方法用于释放锁并阻塞线程,直到被其他线程唤醒。使用不当可能导致死锁、虚假唤醒或逻辑错误。以下是常见问题及修复方案:


常见问题与修复方案

1. 未检查条件(虚假唤醒)
  • 问题wait() 可能被虚假唤醒(即使未收到 notify()),若用 if 检查条件,唤醒后可能条件仍未满足。

    python

    with cond:if not resource_ready:  # ❌ 错误:应用 while 而非 ifcond.wait()
  • 修复:始终用 while 循环检查条件:

    python

    with cond:while not resource_ready:  # ✅ 正确:循环检查条件cond.wait()

2. 未在持有锁时调用 wait()
  • 问题:调用 wait() 前未获取关联锁,抛出 RuntimeError

    python

    cond = threading.Condition()
    cond.wait()  # ❌ 错误:未先获取锁
  • 修复:确保在 with 块或 acquire()/release() 中调用:

    python

    with cond:  # ✅ 正确:自动获取/释放锁while not ready:cond.wait()

3. 未正确配对 notify() 和 wait()
  • 问题notify() 未在修改条件的代码块中调用,导致信号丢失。

    python

    def producer():resource_ready = True  # ❌ 错误:未在锁内修改条件cond.notify()          # 可能错过唤醒
  • 修复修改条件和调用 notify() 必须在同一锁内

    python

    def producer():with cond:resource_ready = True  # ✅ 在锁内修改条件cond.notify()          # 安全唤醒

4. 未使用超时导致永久阻塞
  • 问题:若生产者线程失败,消费者可能永久阻塞。

  • 修复:为 wait() 添加 timeout 参数并处理超时:

    python

    with cond:while not resource_ready:if not cond.wait(timeout=5.0):  # 等待5秒print("Timeout, exiting")break

5. 错误使用 notify() 而非 notify_all()
  • 问题notify() 只唤醒一个线程,若多个线程等待相同条件,可能遗漏唤醒。

  • 修复:需要唤醒所有线程时使用 notify_all()

    python

    with cond:resource_ready = Truecond.notify_all()  # ✅ 唤醒所有等待线程

完整正确示例

python

import threading# 共享资源与条件变量
resource_ready = False
cond = threading.Condition()def consumer():with cond:while not resource_ready:  # 循环检查条件cond.wait()            # 释放锁并等待print("Resource is ready!")def producer():with cond:global resource_readyresource_ready = True     # 修改条件cond.notify_all()         # 唤醒所有等待线程# 启动线程
threading.Thread(target=consumer).start()
threading.Thread(target=producer).start()

关键实践总结

  1. 检查条件:始终用 while 循环检查条件(防虚假唤醒)。

  2. 锁的作用域wait()notify() 及条件修改必须在同一锁内

  3. 唤醒选择

    • notify():唤醒 1 个线程(效率高)。

    • notify_all():唤醒 所有线程(避免遗漏)。

  4. 超时机制:用 wait(timeout=seconds) 防止永久阻塞。

  5. 资源状态:条件变量应关联明确的共享状态(如 resource_ready)。

遵循这些模式可避免 Condition 的常见陷阱,确保线程安全。

http://www.lryc.cn/news/623250.html

相关文章:

  • 《设计模式》装饰模式
  • Tello无人机与LLM模型控制 ROS
  • 二十六、Mybatis-XML映射文件
  • 行为型设计模式:对象协作的舞蹈家(中)
  • 从0到1掌握 Spring Security(第三篇):三种认证方式,按配置一键切换
  • RH134 访问网络附加存储知识点
  • 从舒适度提升到能耗降低再到安全保障,楼宇自控作用关键
  • 19.3 Transformers量化模型极速加载指南:4倍推理加速+75%显存节省实战
  • 立体匹配中的稠密匹配和稀疏匹配
  • RK3568 NPU RKNN(二):RKNN-ToolKit2环境搭建
  • 《MySQL 数据库备份与视图创建全流程:从数据迁移到高效查询实战》
  • MySQL的下载安装(MSI和ZIP版本都有)
  • 利用Qwen大模型进行c++11并发库的学习,与时俱进!!!!
  • 从频繁告警到平稳发布:服务冷启动 CPU 风暴优化实践01
  • 同创物流学习记录1
  • 发文暴论!线性注意力is all you need!
  • 【leetcode】12. 整数转罗马数字
  • 双椒派E2000D开发板LED驱动开发实战指南
  • 【手撕JAVA多线程】1.从设计初衷去看JAVA的线程操作
  • ESP32 C3 开发板使用教程 01-测试显示屏
  • 数据结构之heap算法
  • ollama 自定义模型
  • 黑板架构详解
  • jd-hotkey探测热点key
  • 深入理解 Linux 线程:从概念到虚拟地址空间的全面解析
  • 第5问 对于数据分析领域,统计学要学到什么程度?
  • 2025年睿抗国赛本科组题解
  • 《C语言程序设计》笔记p10
  • 【数据结构入门】二叉树(2)
  • 【数据结构】-2- 泛型