新闻中心

python多线程中的死锁和递归锁用法

2025-12-01
浏览次数:
返回列表
死锁是多线程竞争资源时因循环等待导致程序卡住的现象,如线程A持lock1等lock2、B持lock2等lock1;避免方法是统一加锁顺序并使用RLock支持同线程重复加锁,防止自我阻塞。

python多线程中的死锁和递归锁用法

在Python多线程编程中,死锁(Deadlock)是一个常见且棘手的问题。它通常发生在多个线程竞争多个锁资源时,彼此相互等待对方释放锁,导致所有线程都无法继续执行。

什么是死锁?

假设有两个线程 A 和 B,以及两把锁 lock1 和 lock2:

  • 线程 A 持有 lock1,并试图获取 lock2
  • 线程 B 持有 lock2,并试图获取 lock1

这时,A 等 B 释放 lock2,B 等 A 释放 lock1,形成循环等待,程序卡住——这就是典型的死锁。

示例:产生死锁的代码

import threading
import time
<p>lock1 = threading.Lock()
lock2 = threading.Lock()</p><p>def thread_1():
with lock1:
print("线程1 获取了 lock1")
time.sleep(1)
print("线程1 尝试获取 lock2")
with lock2:
print("线程1 获取了 lock2")</p><p>def thread_2():
with lock2:
print("线程2 获取了 lock2")
time.sleep(1)
print("线程2 尝试获取 lock1")
with lock1:
print("线程2 获取了 lock1")</p><p>t1 = threading.Thread(target=thread_1)
t2 = threading.Thread(target=thread_2)</p><p>t1.start()
t2.start()</p><p>t1.join()
t2.join()

运行这段代码,大概率会卡住,出现死锁。

如何避免死锁?使用递归锁 RLock

虽然 RLock(可重入锁)不能直接解决多锁交叉导致的死锁,但它允许同一个线程多次获取同一把锁,防止因重复加锁导致的自我阻塞。

更重要的是,避免死锁的关键是:保持加锁顺序一致

Narration Box Narration Box

Narration Box是一种语音生成服务,用户可以创建画外音、旁白、有声读物、音频页面、播客等

Narration Box 68 查看详情 Narration Box

改进方案:统一加锁顺序 + 使用 RLock 防止重复加锁问题

import threading
import time
<h1>使用 RLock 替代 Lock,支持同一线程重复进入</h1><p>lock1 = threading.RLock()
lock2 = threading.RLock()</p><p>def worker_1():
print("线程1 开始")
with lock1:
print("线程1 获取 lock1")
time.sleep(0.5)
with lock2:  # 统一先 lock1 再 lock2
print("线程1 获取 lock2")</p><p>def worker_2():
print("线程2 开始")
with lock1:  # 同样先获取 lock1
print("线程2 获取 lock1")
time.sleep(0.5)
with lock2:
print("线程2 获取 lock2")</p&gt;<p>t1 = threading.Thread(target=worker_1)
t2 = threading.Thread(target=worker_2)</p><p>t1.start()
t2.start()</p><p>t1.join()
t2.join()

这个版本中,两个线程都按照 lock1 → lock2 的顺序加锁,避免了循环等待,从而防止死锁。

递归锁 RLock 的典型用途

当一个函数在持有锁的情况下调用另一个也需要同一把锁的函数时,普通 Lock 会导致阻塞,而 RLock 允许这种情况。

import threading
<p>rlock = threading.RLock()</p><p>def func1():
with rlock:
print("func1 已加锁")
func2()  # 调用另一个需要同样锁的函数</p><p>def func2():
with rlock:  # 同一线程可再次获取锁
print("func2 也获得了锁")</p><p>t = threading.Thread(target=func1)
t.start()
t.join()

如果这里用的是 Lock(),程序会在进入 func2 时被自己阻塞。

总结建议

  • 死锁主因是锁的获取顺序不一致或循环等待
  • 使用 threading.RLock 可解决同一线程重复加锁问题
  • 避免死锁的根本方法是:始终以相同顺序获取多个锁
  • 设计时尽量减少锁的数量和嵌套层级
  • 可以使用超时机制(acquire(timeout=))来检测潜在死锁

基本上就这些。掌握锁的使用顺序和选择合适的锁类型,能有效避免多线程中的死锁问题。

以上就是python多线程中的死锁和递归锁用法的详细内容,更多请关注其它相关文章!


# 如何处理  # 莆田网站优化  # 旅游网站系统建设  # 百度霸屏推广一手营销吧TT团队  # seo优化的网站怎么用  # 阜新推广网站建设有用吗  # 东莞网站建设推广策划  # 越秀网站seo优化排名  # 云南seo运营团队排行  # 联盟网站推广  # 网站推广软件需要多少钱  # 是一个  # python  # 如何使用  # 数据处理  # 的是  # 多个  # 加锁  # 多线程  # 递归  # 死锁  # 有锁  # 一加 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: msn官网入口地址手机版 msn官方网站手机最新链接  限制HTML日期输入框的日期选择范围  PHP表单数据传递:如何通过隐藏输入字段获取动态ID  J*aScript类型检查_j*ascript代码规范  MAC的“快捷指令”怎么同步到iPhone_MAC利用iCloud同步所有设备的自动化指令  PHP中高效并行检查多链接状态的教程  Vue.js 图片显示异常排查:理解应用挂载范围与DOM ID唯一性  火锅吃太多会怎样 火锅吃太多会上火吗  Golang如何实现Web文件静态资源服务器_Golang静态资源服务器开发与实践  QQ邮箱网页版入口登录 QQ邮箱在线邮箱官方通道  age动漫网站入口 age动漫官网直接访问入口  神庙逃亡小游戏在线玩 神庙逃亡小游戏入口  将JSON对象数组转置为键值对列表的实用指南  PHP中SSG-WSG API的AES加密实践:正确使用初始化向量  LINQ to XML为何解析失败? 深入理解C# XDocument的异常处理  如何在CSS中使用浮动制作导航栏_float实现水平菜单  天眼查企业查询官网入口 天眼查官方网页版查询  QQ邮箱登录官网首页 腾讯QQ邮箱网页入口  期待已久:小米17 Ultra、小米首款NAS本月登场  J*aScript实现单选按钮与关联输入框的联动禁用教程  Angular中单选按钮的正确使用与常见陷阱解析  mysql通配符支持数字匹配吗_mysql通配符能否用于数字匹配的解析  SteamMachine定价或为699美元 大家想入手吗?  AO3访问入口汇总 AO3网页版同人作品一键直达  Safari怎么安装扩展程序 浏览器插件安装与管理方法【详解】  cad如何更改注释性对象的比例_cad注释性比例调整方法  C++如何检测键盘输入_C++ _kbhit与_getch函数非阻塞输入  实现分段式页面滚动导航:CSS与J*aScript教程  ArrayList与LinkedList核心操作的Big-O复杂度分析  css卡片内容溢出如何处理_使用overflow隐藏或scroll显示内容  CSS实现侧边栏导航项全宽圆角悬停背景效果  Windows 11怎么彻底关闭定位_Windows 11服务中禁用Geolocation  一加 14R 快充无反应_一加 14R 充电优化  Bilibili动漫最新防封地址发布-Bilibili动漫2025年最稳正版入口推荐  狙击外星人小游戏开始_狙击外星人小游戏立即开始  Golang如何优化CPU绑定任务分配策略_Golang CPU任务分配优化实践  Golang如何优雅处理error_Golang error处理最佳实践总结  大象笔记网页版入口 印象笔记网页版登录入口  c++ 命名空间怎么用 c++ namespace使用指南  Python中如何避免重复条件判断:利用数据结构实现动态逻辑  Python自定义类排序:解决lambda键值访问TypeError的实践指南  谷歌google账号注册详细步骤 谷歌账号注册官方教程  PySpark中高效提取字符串右侧可变长度数字:使用regexp_extract  处理嵌套交互式控件:前端可访问性指南  J*aScript中localStorage数据的获取、清洗与格式化教程  QQ邮箱在线登录平台 QQ邮箱个人邮箱网页版入口  在Go Martini框架中高效服务动态生成图像的实践指南  电脑IP地址怎么查 查看本机IP地址的几种方法  火狐浏览器占用内存高卡顿怎么办 火狐浏览器性能优化设置技巧  Linux如何排查内存不足OOME问题_LinuxOOM分析教程 

搜索