python互斥锁与死锁-多任务编程

一、互斥锁与死锁

1.1 互斥锁

互斥锁:对共享数据进行锁定,保证同一时刻只能有一个线程去操作,是多个线程一起去抢,抢到锁的线程先执行,没抢到的等待互斥锁使用完释放后再去抢

使用步骤

lock = threading.Lock()   # 创建全局互斥锁
lock.acquire()   # 上锁
# ……执行代码,保证同一时刻只有一个线程去操作,对共享数据进行锁定
lock.release()   # 释放锁
  • 互斥锁能保证多个线程访问共享数据不会出现数据错误问题
  • acquire与release之间的代码同一时刻只能有一个线程去操作,能够确保某段关键代码只能由一个线程从头到尾完整执行
  • 若调用acquire方法时其他线程已经使用了该互斥锁,acquire方法会堵塞,直至该互斥锁释放才能再上锁
  • 加上互斥锁多任务瞬间变为单任务,影响代码执行效率,性能会下降,同一时刻只能有一个线程去执行
  • 加上互斥锁,哪个线程抢到锁就先执行,其余的等待
  • 若使用不当易出现死锁,要在合适的地方释放锁

举例如下: 

lock = threading.Lock()   # 创建全局互斥锁
sum = 0
def sum1():
    lock.acquire()  # 上锁
    for i in range(1000000):   # 实现一百万次全局变量加1
        global sum
        sum += 1
    print('总和为:', sum, 'sum两倍为:', sum*2)
    lock.release()  # 释放锁
def sum2():
    lock.acquire()  # 上锁
    for i in range(1000000):
        global sum
        sum += 1
    print('总和为:', sum)
    lock.release()  # 释放锁
if __name__ == '__main__':
    sum1_thread = threading.Thread(target=sum1)
    sum2_thread = threading.Thread(target=sum2)
    sum1_thread.start()
    sum2_thread.start()

输出:
总和为: 1000000 sum两倍为: 2000000
总和为: 2000000

1.2 死锁

死锁:一直等待对方释放锁的情景,死锁会造成应用程序停止响应,不再处理其他任务,应用程序无法继续往下执行

举例如下:

import threading
import time
lock = threading.Lock()  # 创建互斥锁
def getValue(i):
    lock.acquire()  # 上锁
    print(threading.current_thread())
    list = [0, 2, 5]
    if i >= len(list):
        print('下标为%d,已越界' % i)
        return
    print('下标为%d的值为:%d' % (i, list[i]))
    time.sleep(0.2)
    lock.release()   # 释放锁
if __name__ == '__main__':
    for i in range(5):
        value_thread = threading.Thread(target=getValue, args=(i,))
        value_thread.start()

输出:
<Thread(Thread-1, started 37860)>
下标为0的值为:0
<Thread(Thread-2, started 27920)>
下标为1的值为:2
<Thread(Thread-3, started 37420)>
下标为2的值为:5
<Thread(Thread-4, started 33532)>
下标为3,已越界
# 执行未结束,死锁状态
--------------------------避免死锁---------修改-------------
def getValue(i):
    lock.acquire()  # 上锁
    print(threading.current_thread())
    list = [0, 2, 5]
     if i >= len(list):
        print('下标为%d,已越界' % i)
        lock.release()   # 下标越界要释放锁,以让后面的线程继续可以取值
        return
    print('下标为%d的值为:%d' % (i, list[i]))
    time.sleep(0.2)
    lock.release()   # 释放锁

输出:
<Thread(Thread-1, started 21816)>
下标为0的值为:0
<Thread(Thread-2, started 35400)>
下标为1的值为:2
<Thread(Thread-3, started 27992)>
下标为2的值为:5
<Thread(Thread-4, started 32780)>
下标为3,已越界
<Thread(Thread-5, started 25208)>
下标为4,已越界
# 正常结束

1.3 推荐学习 

python进程与线程-多任务编程

学习导航:http://xqnav.top/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

learning-striving

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值