使用run_in_executor多线程执行时字典引用致数据交叉的问题
解决多线程执行函数时的字典数据交叉问题
问题根源
你遇到的核心问题是Python里字典赋值是引用传递,不是值传递。执行frame2 = frame1后,两个变量指向的是同一个字典对象——修改frame2['data']本质上是修改了这份共享的字典数据,所以两个线程操作的是同一份内容,和executor的名称没有关系。
解决方案
要让两个线程操作独立的字典,必须创建字典的独立副本,常用两种方式:
1. 浅拷贝(适合单层字典)
用字典自带的copy()方法创建副本,适用于没有嵌套可变对象的字典:
frame1 = {'data': 'hello'} # 创建frame1的独立副本 frame2 = frame1.copy() frame2['data'] = 'bye' executor = concurrent.futures.ThreadPoolExecutor() sys.loop.run_in_executor(executor, MetodoInsertar, frame1) executorpush = concurrent.futures.ThreadPoolExecutor() sys.loop.run_in_executor(executorpush, MetodoInsertar, frame2)
2. 深拷贝(适合嵌套字典)
如果字典里包含嵌套的可变对象(比如子字典、列表),浅拷贝无法完全隔离数据,需要用copy.deepcopy():
import copy frame1 = {'data': 'hello', 'nested': {'key': 'value'}} # 递归创建完全独立的副本 frame2 = copy.deepcopy(frame1) frame2['data'] = 'bye' frame2['nested']['key'] = 'new_value' # 此修改不会影响frame1的嵌套内容 executor = concurrent.futures.ThreadPoolExecutor() sys.loop.run_in_executor(executor, MetodoInsertar, frame1) executorpush = concurrent.futures.ThreadPoolExecutor() sys.loop.run_in_executor(executorpush, MetodoInsertar, frame2)
额外优化提示
不需要创建多个ThreadPoolExecutor实例,单个executor就能提交多个线程任务,简化代码:
executor = concurrent.futures.ThreadPoolExecutor(max_workers=2) sys.loop.run_in_executor(executor, MetodoInsertar, frame1) sys.loop.run_in_executor(executor, MetodoInsertar, frame2)
内容的提问来源于stack exchange,提问作者Santiago Trujillo Terán
相关产品推荐
相关产品推荐

