python多线程————4、线程同步之Lock,RLock

     在多线程同时请求同一个资源并进行修改时可能会造成结果出错,例如共享变量

     

from dis import dis
import threading
a = 0
def add():
    global a
    a += 1

def desc():
    global a
    a -= 1

print(dis(add))
print(dis(desc))

thread_add = threading.Thread(target=add)
thread_desc = threading.Thread(target=desc)
thread_add.start()
thread_desc.start()
thread_add.join()
thread_desc.join()
print(a)

 在上面的代码中存在一个什么问题呢?虽然运行没能看出什么问题,看dis这个模块打印出的内容,一个+=运算是先load a 然后load 1 然后做运算再把结果赋值给a。那问题来了如果a同时被desc和add 加载呢,那desc和add加载进去的a值都为0,那a做add和desc运算后结果可能为1 或者-1而不是0。

              0 LOAD_GLOBAL              0 (a)
              2 LOAD_CONST               1 (1)
              4 INPLACE_ADD
              6 STORE_GLOBAL             0 (a)
              8 LOAD_CONST               0 (None)

要怎么解决这个同步问题呢,解决方法是给资源加把锁Lock,RLock(可重如的锁)

from threading import Lock
total = 0
lock = Lock()
def add():
    global total
    global lock
    #1.do something1
    #2. io操作
    #3.do someting3
    for i in range(1000000):
        lock.acquire()
        total += 1
        lock.release()
def desc():
    global total
    global lock
    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)
print(dis(add))

 Lock在使用过程中不可以重入,重入会造成死锁,比如

lock.acquire()
lock.acquire()

而CLock是在同一线程中是可以重入的,但要记得释放相同数量的锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值