MST

星途 面试题库

面试题:Python锁机制下如何处理死锁及优化性能

在使用Python的锁机制时,死锁是一个常见问题。请阐述死锁产生的原因,并给出至少两种避免死锁的方法,同时说明在避免死锁的过程中如何优化程序性能,可结合代码示例进行说明。
20.5万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

死锁产生的原因

  1. 资源竞争:多个线程或进程竞争有限的资源,例如多个线程都需要获取两个不同的锁才能完成任务。
  2. 锁的获取顺序不一致:如果不同线程获取锁的顺序不同,就可能导致死锁。例如,线程A先获取锁1,再获取锁2;而线程B先获取锁2,再获取锁1,这样就可能出现死锁。
  3. 缺乏资源分配策略:没有合理的资源分配算法,导致某些线程一直占有资源不释放,其他线程无法获取资源。

避免死锁的方法

  1. 按照固定顺序获取锁
    • 原理:所有线程都按照相同的顺序获取锁,这样可以避免锁获取顺序不一致导致的死锁。
    • 代码示例
import threading

lock1 = threading.Lock()
lock2 = threading.Lock()


def thread_function():
    with lock1:
        print("Thread has acquired lock1")
        with lock2:
            print("Thread has acquired lock2")


t = threading.Thread(target=thread_function)
t.start()
t.join()
  1. 使用超时机制
    • 原理:设置获取锁的超时时间,如果在规定时间内无法获取锁,则放弃获取并进行相应处理,从而避免线程无限等待。
    • 代码示例
import threading
import time


lock1 = threading.Lock()
lock2 = threading.Lock()


def thread_function():
    if lock1.acquire(timeout=1):
        print("Thread has acquired lock1")
        if lock2.acquire(timeout=1):
            print("Thread has acquired lock2")
            lock2.release()
        lock1.release()


t = threading.Thread(target=thread_function)
t.start()
t.join()

避免死锁过程中的性能优化

  1. 减少锁的持有时间
    • 原理:尽量缩短线程持有锁的时间,这样可以减少其他线程等待的时间,提高整体性能。
    • 代码示例
import threading


lock = threading.Lock()
data = []


def thread_function():
    with lock:
        # 只在必要的操作时持有锁
        local_data = [1, 2, 3]
        data.extend(local_data)


threads = []
for _ in range(5):
    t = threading.Thread(target=thread_function)
    threads.append(t)
    t.start()

for t in threads:
    t.join()
print(data)
  1. 使用细粒度锁
    • 原理:将大的锁拆分成多个小的锁,每个锁控制一部分资源,这样不同线程可以同时访问不同部分的资源,提高并发性能。
    • 代码示例
import threading


lock1 = threading.Lock()
lock2 = threading.Lock()
data1 = []
data2 = []


def thread1_function():
    with lock1:
        data1.append(1)


def thread2_function():
    with lock2:
        data2.append(2)


t1 = threading.Thread(target=thread1_function)
t2 = threading.Thread(target=thread2_function)
t1.start()
t2.start()
t1.join()
t2.join()
print(data1)
print(data2)