MST
星途 面试题库

面试题:Python条件检查在并发场景下的挑战与应对

在一个多线程的Python应用程序中,有多个线程同时对共享数据进行操作。需要在主线程中检查多个条件,这些条件涉及到共享数据的状态,例如共享列表的长度变化、共享字典中特定键值对的更新等。请描述如何在并发场景下安全且高效地检查这些条件,编写相关代码示例,并阐述可能遇到的并发问题及解决方案,包括使用哪些同步机制等。
17.2万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

1. 安全且高效检查条件的方法

在Python多线程环境下,为了安全且高效地检查涉及共享数据状态的条件,可以使用锁(Lock)、条件变量(Condition)等同步机制。

2. 代码示例

import threading
import time


# 共享数据
shared_list = []
shared_dict = {}
lock = threading.Lock()
condition = threading.Condition(lock)


def worker1():
    global shared_list
    with lock:
        for i in range(5):
            shared_list.append(i)
            condition.notify_all()  # 通知其他线程共享数据已更新
            time.sleep(1)


def worker2():
    global shared_dict
    with lock:
        for i in range(5):
            shared_dict[f'key_{i}'] = i
            condition.notify_all()  # 通知其他线程共享数据已更新
            time.sleep(1)


def main_thread():
    with lock:
        while True:
            # 检查共享列表长度变化
            if len(shared_list) >= 3:
                print(f"共享列表长度达到3,当前长度: {len(shared_list)}")
            # 检查共享字典特定键值对更新
            if 'key_2' in shared_dict and shared_dict['key_2'] == 2:
                print("共享字典中key_2的值已更新为2")
            condition.wait(timeout=1)  # 等待数据更新通知,设置超时防止死等
            if len(shared_list) >= 5 and len(shared_dict) >= 5:
                break


if __name__ == "__main__":
    t1 = threading.Thread(target=worker1)
    t2 = threading.Thread(target=worker2)
    t1.start()
    t2.start()
    main_thread()
    t1.join()
    t2.join()

3. 可能遇到的并发问题及解决方案

  • 竞态条件(Race Condition):多个线程同时访问和修改共享数据,导致数据不一致。解决方案是使用锁(Lock),确保同一时间只有一个线程可以访问共享数据。
  • 死锁(Deadlock):两个或多个线程相互等待对方释放资源,导致程序无法继续执行。为避免死锁,要合理安排锁的获取顺序,避免嵌套锁,并且尽量缩短持有锁的时间。
  • 活锁(Livelock):线程不断重试相同的操作,但由于其他线程也在同时进行操作,导致没有线程能取得进展。解决方案是在重试操作中引入随机延迟,避免线程间的持续冲突。
  • 饥饿(Starvation):某个线程由于其他线程频繁获取资源,而长时间无法获取到所需资源。可以通过公平调度算法,例如使用Conditionacquire方法的timeout参数,设置等待时间,防止某个线程长时间等待。