将动态dict传递给python线程的结果也是一样的
我试图创建一个将动态dict传递给python线程的结果也是一样的,python,python-3.x,multithreading,dictionary,Python,Python 3.x,Multithreading,Dictionary,我试图创建一个dict,然后动态地修改该dict,将dict传递给一个线程。我把基本程序归结为以下几点: import threading some_dict = {"1": "Spam", "2": "Bacon", "3": "Eggs"} some_list = ["foo", "bar", "test", &
dict
,然后动态地修改该dict
,将dict
传递给一个线程。我把基本程序归结为以下几点:
import threading
some_dict = {"1": "Spam", "2": "Bacon", "3": "Eggs"}
some_list = ["foo", "bar", "test", "test2"]
def threader(dict):
print("start")
thread_list = []
i = 1
while i < 4:
print("adding...")
some_dict[str(i)] = some_list[i]
print(some_dict)
new_thread = threading.Thread(target=printer, args=(some_dict,))
thread_list.append(new_thread)
i += 1
print("dicts:")
for thread in thread_list:
thread.start()
for thread in thread_list:
thread.join()
print("end")
def printer(dict):
print(dict)
if __name__ == '__main__':
threader(some_dict)
我做错了什么?为什么线都是一样的
使用Python3.9。定义一个新字典,
d
,在循环的每次迭代中使用.copy()
,以避免覆盖原始字典。此外,避免将变量命名为内置的名称:
import threading
some_dct = {"1": "Spam", "2": "Bacon", "3": "Eggs"}
some_list = ["foo", "bar", "test", "test2"]
def threader(dct):
print("start")
thread_list = []
i = 1
while i < 4:
d = some_dct.copy()
print("adding...")
d[str(i)] = some_list[i]
print(d)
new_thread = threading.Thread(target=printer, args=(d,))
thread_list.append(new_thread)
i += 1
print("dcts:")
for thread in thread_list:
thread.start()
for thread in thread_list:
thread.join()
print("end")
def printer(dct):
print(dct)
if __name__ == '__main__':
threader(some_dct)
导入线程
some_dct={“1”:“垃圾邮件”、“2”:“培根”、“3”:“鸡蛋”}
some_list=[“foo”、“bar”、“test”、“test2”]
def螺纹机(dct):
打印(“开始”)
线程列表=[]
i=1
而我<4:
d=一些文件副本()
打印(“添加…”)
d[str(i)]=某些清单[i]
印刷品(d)
new_thread=threading.thread(target=printer,args=(d,))
线程列表。追加(新线程)
i+=1
打印(“DCT:)
对于线程列表中的线程:
thread.start()
对于线程列表中的线程:
thread.join()
打印(“结束”)
def打印机(dct):
打印(dct)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
穿线机(部分)
最简单的解决方案就是改变:
new_thread = threading.Thread(target=printer, args=(some_dict,))
致:
因此,每个线程在创建时都会得到一个
dict
的浅拷贝。如前所述,您将别名传递给一个共享的dict
到所有线程,并且在循环完成之前不启动任何一个线程(此时应用了所有突变,所有线程都看到了最终状态)。我想您应该将dict的“副本”传递给线程:new\u thread=threading.thread(target=printer,args=({k:v代表某些目录项()中的(k,v))
您说的是“最近的线程”正在覆盖所有其他线程,但它不是。您的主线程有一个dict
。它会多次更新它,但会将同一个dict
的别名传递给每个线程。并且在构建所有线程之前,它不会启动任何线程,因此所有线程都会在dict
中设置最终值后启动(这至少避免了一场竞赛)。@MauriceMeyer:任何运算理解都是毫无意义的冗长/缓慢。一个简单的some_dict.copy()
或dict(some_dict)
将更有效、更不冗长地完成这项工作。或者copy.deepcopy(some_dict)
如果值本身可能发生变异,而不仅仅是重新分配。传递的dict
是否应该逐步变异(因此线程1的变异仍然是线程2的变异)或者它总是被认为是某种修改吗?@MauriceMeyer这起作用了!虽然我真的不知道如何…谢谢你的输入。不幸的是,我按原样插入了你的代码,它仍然打印相同的内容。@AnnZen:这不起作用,因为d=some\u dct
没有复制;d
同样是一个别名在OP的代码中的部分内容。@Chris哦,是的!需要有.copy()
。我的更新现在应该可以运行了,@ShadowRanger谢谢!
new_thread = threading.Thread(target=printer, args=(some_dict,))
new_thread = threading.Thread(target=printer, args=(some_dict.copy(),))