挑战
- 竞态条件:由于多个线程同时执行,当一个线程在
if
语句判断条件之后,执行操作之前,其他线程可能已经修改了共享字典,导致判断条件失效,操作基于错误的前提执行。例如,一个线程判断字典中某个键不存在,准备添加该键值对,但在执行添加操作前,另一个线程已经添加了该键。
- 数据不一致:如果没有正确的错误处理,在某个线程执行字典操作过程中出现错误(如内存不足导致添加键值对失败),可能会使共享字典处于不一致的状态,影响其他线程后续操作。
利用锁机制和异常捕获确保正确性和稳定性
- 锁机制:使用
threading.Lock
来保证同一时间只有一个线程能够访问和修改共享字典。在进入if
语句判断前获取锁,操作完成后释放锁。
- 异常捕获:在对字典进行操作的代码块中使用
try - except
语句捕获可能出现的异常,如KeyError
(访问不存在的键)、MemoryError
(内存不足)等,确保在出现异常时能够正确处理,不会让程序崩溃或导致数据不一致。
关键代码片段
import threading
# 共享字典
shared_dict = {}
# 创建锁对象
lock = threading.Lock()
def thread_function(condition):
global shared_dict
with lock:
try:
if condition:
# 添加键值对
shared_dict['key'] = 'value'
else:
# 更新值
if 'key' in shared_dict:
shared_dict['key'] = 'new_value'
except KeyError as e:
print(f"捕获到KeyError: {e}")
except MemoryError as e:
print(f"捕获到MemoryError: {e}")
# 创建并启动线程
thread1 = threading.Thread(target=thread_function, args=(True,))
thread2 = threading.Thread(target=thread_function, args=(False,))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
设计思路
- 锁机制:
with lock:
语句块确保了在进入if
语句判断以及后续对共享字典操作的过程中,其他线程无法同时访问共享字典,避免了竞态条件。
- 异常捕获:
try - except
语句块在字典操作可能出现异常的地方进行捕获,根据不同的异常类型进行相应处理,这里简单地打印异常信息,实际应用中可以进行更复杂的处理,如记录日志、回滚操作等,保证共享字典的一致性和程序的稳定性。