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

在Python多线程编程中,死锁(Deadlock)是一个常见且棘手的问题。它通常发生在多个线程竞争多个锁资源时,彼此相互等待对方释放锁,导致所有线程都无法继续执行。
假设有两个线程 A 和 B,以及两把锁 lock1 和 lock2:
这时,A 等 B 释放 lock2,B 等 A 释放 lock1,形成循环等待,程序卡住——这就是典型的死锁。
示例:产生死锁的代码
立即学习“Python免费学习笔记(深入)”;
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 防止重复加锁问题
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><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 的顺序加锁,避免了循环等待,从而防止死锁。
当一个函数在持有锁的情况下调用另一个也需要同一把锁的函数时,普通 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 时被自己阻塞。
acquire(timeout=))来检测潜在死锁基本上就这些。掌握锁的使用顺序和选择合适的锁类型,能有效避免多线程中的死锁问题。
以上就是python多线程中的死锁和递归锁用法的详细内容,更多请关注php中文网其它相关文章!
python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号