11-4 线程同步 - Lock、RLock

本文探讨了在多线程环境下使用锁Lock确保代码线程安全的方法,并通过实例展示了如何利用Lock和RLock避免线程间的竞态条件。同时,文章分析了锁可能带来的性能影响及死锁问题,包括两种典型的死锁场景,并提出了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. Lock
    加入锁Lock之后,在lock.acquire()和lock.release()之间的代码是线程安全的
total=0
lock=Lock()
def add():
    #1. dosomething1
    #2. io操作
    #3. dosomething3
    global total
    for i in range(1000000):
        lock.acquire() #加锁
        total +=1
        lock.release() #释放

def desc():
    global total
    for i in range(1000000):
        lock.acquire() #加锁
        total -=1
        lock.release() #释放

import threading
thread1=threading.Thread(target=add)
thread2=threading.Thread(target=desc)
thread1.start()
thread2.start()

thread1.join()
thread2.join()
print(total)

#结果:0
  • 用锁会影响性能
  • 锁会引起死锁

引起死锁的情况1

lock.acquire()
lock.acquire() #在lock未释放,又加锁,就引起了死锁
# do something
lock.release()

引起死锁的情况2

#使用伪代码说明
A需要变量a和b,B需要变量a和b
A首先对a加锁,B对b加锁,A需要b,但是已经被B加锁,那么A无法对b加锁,导致了死锁
A(a,b)
acquire(a)
acquire(b)

B(a, b)
acquire(b)
acquire(a)

2.RLock:在同一个线程里面,可以连续调用多次acquire,一定要注意acquire的次数要和release的次数相等
代码如上,只要把Lock改成RLock即可,这样可以解决Lock死锁情况1的问题

lock=Lock() ----> lock=RLock()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值