python 字典的线程安全问题
Python 中的标准字典 dict 并不是线程安全的,因为它在并发写入时可能会导致数据竞争(data race)问题,从而导致程序出现错误或崩溃。
如果需要在多线程环境下安全地使用字典,可以考虑使用线程安全的字典实现,例如 collections.defaultdict 或 multiprocessing.Manager().dict()。
defaultdict 是 Python 标准库中的一个类,它与 dict 类似,但是可以在创建时指定默认值。如果使用 defaultdict 存储计数器,就可以避免在增加计数时出现 KeyError 错误。以下是一个示例代码:
import collections import threading counter = collections.defaultdict(int) lock = threading.Lock() def count(key): with lock: counter[key] += 1 threads = [threading.Thread(target=count, args=('a',)) for i in range(10)] for thread in threads: thread.start() for thread in threads: thread.join() print(counter) # 输出 defaultdict(<class 'int'>, {'a': 10})
在上述代码中,我们使用 defaultdict(int) 创建了一个默认值为 0 的计数器 counter,然后使用互斥锁 lock 来保证多线程安全。
另一种线程安全的字典实现是 multiprocessing.Manager().dict(),它是在 multiprocessing 模块中提供的。以下是一个示例代码:
import multiprocessing def worker(d, key): with d.get_lock(): d[key] += 1 manager = multiprocessing.Manager() d = manager.dict() processes = [multiprocessing.Process(target=worker, args=(d, 'a')) for i in range(10)] for process in processes: process.start() for process in processes: process.join() print(d) # 输出 {'a': 10}
在上述代码中,我们使用 multiprocessing.Manager() 创建了一个进程共享的字典 d,然后使用 d.get_lock() 获取锁来保证多进程安全。
相关文章