MST
星途 面试题库

面试题:Python多线程数据处理中的同步问题

在一个数据处理任务中,有多个线程需要同时访问和修改一个共享的字典。该字典存储了不同用户的积分信息,键为用户名,值为积分。请设计一个方案,使用Python多线程安全地实现以下操作:当一个用户登录时,增加其积分10分;当用户执行特定任务时,扣除其积分5分。阐述如何使用锁机制或其他同步原语来避免数据竞争。
15.5万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试
import threading

# 创建一个锁对象
lock = threading.Lock()
# 共享的字典,存储用户积分信息
user_points = {}

def login_user(username):
    global user_points
    with lock:
        if username in user_points:
            user_points[username] += 10
        else:
            user_points[username] = 10

def perform_task(username):
    global user_points
    with lock:
        if username in user_points and user_points[username] >= 5:
            user_points[username] -= 5
        else:
            print(f"{username} 积分不足,无法执行任务。")

# 示例使用
if __name__ == "__main__":
    # 创建线程
    thread1 = threading.Thread(target=login_user, args=("user1",))
    thread2 = threading.Thread(target=perform_task, args=("user1",))

    # 启动线程
    thread1.start()
    thread2.start()

    # 等待线程结束
    thread1.join()
    thread2.join()

    print(user_points)

解释

  1. 锁机制:使用 threading.Lock() 创建一个锁对象。在需要访问和修改共享字典 user_points 的函数中,使用 with lock: 语句块来获取锁。这确保了在同一时间只有一个线程可以进入这个语句块,从而避免数据竞争。
  2. login_user 函数:当用户登录时,使用锁来确保在修改用户积分时不会有其他线程干扰。如果用户已存在,则增加10分;如果用户不存在,则初始化积分为10分。
  3. perform_task 函数:当用户执行特定任务时,同样使用锁来保护共享字典。检查用户是否存在且积分是否足够,若满足条件则扣除5分,否则提示积分不足。
  4. 示例使用:在 __main__ 部分创建并启动两个线程,一个模拟用户登录,另一个模拟用户执行任务。最后等待线程结束并打印最终的用户积分字典。