MST

星途 面试题库

面试题:Python多线程环境下修改列表元素的潜在问题及解决办法

在Python的多线程编程场景中,有一个共享列表,多个线程会同时对列表元素进行修改操作。请阐述可能会出现哪些问题,并说明如何使用合适的同步机制(如锁、信号量等)来解决这些问题,给出具体的代码实现。
26.0万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

可能出现的问题

  1. 数据竞争:多个线程同时访问和修改共享列表时,由于线程执行顺序的不确定性,可能导致最终结果与预期不符。例如,一个线程读取列表中的某个值,在另一个线程修改该值后,第一个线程再进行计算,这就会产生错误的计算结果。

解决方案及代码实现

  1. 使用锁(Lock
import threading


shared_list = []
lock = threading.Lock()


def modify_list():
    global shared_list
    with lock:
        # 模拟修改操作
        shared_list.append(1)


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


for t in threads:
    t.join()


print(shared_list)

在上述代码中,通过lock对象的上下文管理器(with语句)来确保在任何时刻只有一个线程可以访问和修改共享列表shared_list。进入with块时自动获取锁,离开with块时自动释放锁。

  1. 使用信号量(Semaphore
import threading


shared_list = []
semaphore = threading.Semaphore(1)


def modify_list():
    global shared_list
    semaphore.acquire()
    try:
        # 模拟修改操作
        shared_list.append(1)
    finally:
        semaphore.release()


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


for t in threads:
    t.join()


print(shared_list)

这里使用Semaphore,并将初始值设为1,作用与Lock类似,都是保证同一时间只有一个线程能进入临界区修改共享列表。acquire方法获取信号量,如果信号量的值为0则等待,release方法释放信号量。在try - finally块中确保无论修改操作是否成功,信号量都会被正确释放。