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()

输出:

下标为0的值为:0

下标为1的值为:2

下标为2的值为:5

下标为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()   # 释放锁

输出:

下标为0的值为:0

下标为1的值为:2

下标为2的值为:5

下标为3,已越界

下标为4,已越界
# 正常结束

1.3 推荐学习 

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

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

你可能感兴趣的:(多任务编程,python,开发语言,死锁,互斥锁,多任务编程)