死锁

学习目标

  • 能够知道产生死锁的原因

1. 死锁的概念

死锁: 一直等待对方释放锁的情景就是死锁

为了更好的理解死锁,来看一个现实生活的效果图:

死锁

说明:

现实社会中,男女双方一直等待对方先道歉的这种行为就好比是死锁。

死锁的结果

  • 会造成应用程序的停止响应,不能再处理其它任务了。

2. 死锁示例

需求:

根据下标在列表中取值, 保证同一时刻只能有一个线程去取值

import threading
import time

# 创建互斥锁
lock = threading.Lock()


# 根据下标去取值, 保证同一时刻只能有一个线程去取值
def get_value(index):

    # 上锁
    lock.acquire()
    print(threading.current_thread())
    my_list = [3,6,8,1]
    # 判断下标释放越界
    if index >= len(my_list):
        print("下标越界:", index)
        return
    value = my_list[index]
    print(value)
    time.sleep(0.2)
    # 释放锁
    lock.release()


if __name__ == '__main__':
    # 模拟大量线程去执行取值操作
    for i in range(30):
        sub_thread = threading.Thread(target=get_value, args=(i,))
        sub_thread.start()

3. 避免死锁

  • 在合适的地方释放锁
import threading
import time

# 创建互斥锁
lock = threading.Lock()


# 根据下标去取值, 保证同一时刻只能有一个线程去取值
def get_value(index):

    # 上锁
    lock.acquire()
    print(threading.current_thread())
    my_list = [3,6,8,1]
    if index >= len(my_list):
        print("下标越界:", index)
        # 当下标越界需要释放锁,让后面的线程还可以取值
        lock.release()
        return
    value = my_list[index]
    print(value)
    time.sleep(0.2)
    # 释放锁
    lock.release()


if __name__ == '__main__':
    # 模拟大量线程去执行取值操作
    for i in range(30):
        sub_thread = threading.Thread(target=get_value, args=(i,))
        sub_thread.start()

4. 小结

  • 使用互斥锁的时候需要注意死锁的问题,要在合适的地方注意释放锁。
  • 死锁一旦产生就会造成应用程序的停止响应,应用程序无法再继续往下执行了。