Python 当另一个线程将数据添加到字典中时,是否可以迭代字典?

Python 当另一个线程将数据添加到字典中时,是否可以迭代字典?,python,dictionary,Python,Dictionary,我有一个Python应用程序,其中thread1调用API查看“准备下载哪些报告”,并将该report\u id发送给thread2,后者“下载/处理这些报告”。我试图确定如果thread1向dict添加项目,如果thread2在dict上迭代,会发生什么。现在,在使用thread2之前,我会复制一份 两个问题 我可以反复阅读一本不断变化的词典吗?我目前a)在我迭代之前复制一份dict,b)迭代dict的副本,c)对于dict副本上循环“处理”的项目,我从“原始”dict中删除密钥,因此在下一个

我有一个Python应用程序,其中thread1调用API查看“准备下载哪些报告”,并将该
report\u id
发送给thread2,后者“下载/处理这些报告”。我试图确定如果thread1向dict添加项目,如果thread2在dict上迭代,会发生什么。现在,在使用thread2之前,我会复制一份

两个问题

  • 我可以反复阅读一本不断变化的词典吗?我目前a)在我迭代之前复制一份dict,b)迭代dict的副本,c)对于dict副本上循环“处理”的项目,我从“原始”dict中删除密钥,因此在下一个循环中,它不会重新处理相同的项目

  • 如果我不能迭代一个不断变化的dict,我需要像下面这样使用锁来复制。这样做对吗

  • lock=threading.lock()
    尽管如此:
    带锁:#复制dict以防止冲突
    reports\u to\u call\u copy=self.reports\u to\u call.copy()
    对于行内报告\u至\u调用\u副本:
    #从原始dict中进行填充并删除项目,这样在下一个循环中它不会处理两次。
    被杀死=自我。杀死。等待(180)
    如果被杀:
    打印(“杀戮-请求报告”)
    打破
    del self.reports\u to\u call[用户,报告名称]
    
  • 不,即使从同一线程更改了字典,也不可能迭代更改的字典。最简单的可复制示例:
  • >d=dict()
    >>>d['a']=10
    >>>对于d.项()中的k,v:
    ...     德尔d['a']
    ...
    回溯(最近一次呼叫最后一次):
    文件“”,第1行,在
    RuntimeError:字典在迭代期间更改了大小
    
  • 任何操作字典的代码(如下面的
    del
    语句)也必须获取锁,否则,它可能会在线程创建深度副本时随时删除项,从而可能导致相同的问题,尤其是如果字典大小足够大,删除过程可能会中断深度副本

  • 谢谢,这很有帮助。我不知道那些戴尔电话是否需要锁。假设self.reports\u to\u call.copy()也被认为是一种交互,这是我唯一一次迭代reports\u to\u调用。主循环迭代一个名为reports\u to\u call\u copy的reports\u to\u call副本。在执行删除操作时,永远不会运行.copy()。也就是说,我从另一个线程向reports\u-to\u调用添加报告。添加可能与reports\u to\u call\u copy=self.reports\u to\u call.copy发生的时间相同。你确定吗?如果同一个方法(您的整个代码段)在一行中被调用两次,第一个调用获取锁,另一个调用缺少锁,然后当第一个调用释放锁(继续执行…删除条目)时,第二个调用获取锁并进行深度复制,该怎么办?这里可能存在冲突。santos-我的代码片段acts是它自己的线程,在启动时只调用一次。所以从技术上说我会没事的,或者至少我这么认为。但随着我做了更多的研究,许多最佳实践似乎都建议在您认为可能不需要锁的地方使用锁。基于此,我们建议修改这些字典的所有代码都包含一个锁