Ale*_*lli 63
其他答案已经正确解决了你的实际问题:
这是否意味着我可以或不可以在迭代它时修改字典中的项目?
解释说,线程安全无关这个问题,并且在任何情况下,不,你不能在遍历它修改的字典.
但是,您的问题标题是关于线程安全的,您可以从以下开始:
有人说python字典是线程安全的
我不知道"有些人"是谁,但是,如果他们确实说(而不是你误解了他们所说的状态;-)没有严格的资格,他们就错了.
一些操作,那些不改变键组在快译通,恰好是线程安全的在当前的CPython实现-但你应该没有指望,除非你严格控制Python版本下,你的代码将运行,因为Python的语言规范不能保证这样的线程安全性,因此其他实现(包括CPython的未来版本)可能不会提供它.
如果每个线程只是"读取"dict(索引它,循环它等),并且没有线程对它执行任何赋值或删除,那么这种情况在当前的CPython实现中是安全的.实际上,如果某个线程为已经存在的键分配了一个新值,那么它也是线程安全的(其他线程可能会看到该键的前一个值,或者下一个值,具体取决于线程如何定时,但是在当前的CPython实现中,不会出现崩溃,没有死锁,也不会出现疯狂的价值观.
然而,诸如d[k] += 1(假设k先前存在,并且其值为数字)之类的操作不正确地说是线程安全的(比其他情况更多+=!)因为它可以被视为d[k] = d[k] + 1- 可能发生在两个线程中竞争条件既读取旧值d[k],又将其递增1,并将相同的新值存储在槽中...所以总体效果是将其增加一个,而不是通常发生的两个.
回到你的另一个问题......"只读"字典,并为字典中已经存在的键指定新值,这也是你可以在循环体中进行迭代的事情 - 你可以不改变dict中的键组(不能添加任何键,也不能删除任何键),但允许为现有键设置新值的具体操作.在这种情况下允许的操作确实包括+=在线程情况下会出现问题.例如:
>>> d = dict.fromkeys(range(5), 0)
>>> for k in d: d[k] += 1
...
>>> d
{0: 1, 1: 1, 2: 1, 3: 1, 4: 1}
Run Code Online (Sandbox Code Playgroud)
而这种行为是由Python的标准化语义保证,所以语言的不同实现都应该保护它.
Joh*_*ooy 14
如果您尝试迭代迭代之间已更改大小的字典,则python的最新版本将引发异常.
>>> d={'one':1, 'two':2}
>>> for x in d:
... d['three']=3
... print x
...
two
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
Run Code Online (Sandbox Code Playgroud)
请注意,您不需要使用线程来查看此内容
| 归档时间: |
|
| 查看次数: |
24586 次 |
| 最近记录: |