检查字典中的键是否是原子操作?

2024-05-19 18:41:47 发布

您现在位置:Python中文网/ 问答频道 /正文

正在检查一个键是否在字典中-if key in mydict-一个原子操作?在

如果不是,如果一个线程在检查一个键,而另一个线程正在修改字典,会不会有任何负面影响?检查线程不会修改字典,它只是根据键的存在而表现不同。在


Tags: keyinif字典线程mydict原子负面影响
1条回答
网友
1楼 · 发布于 2024-05-19 18:41:47

我不认为“原子”是你真正感兴趣的。在

如果您没有使用CPython(或者您正在使用,但是其中一个线程正在运行不在GIL下的C代码…),那么它肯定不是原子的,但是在某些情况下它可能是安全的。在

如果您使用CPython,那么从in是一个字节码操作(COMPARE_OP 6)的意义上讲,这是原子性的,从更有用的意义上说,实际的哈希表查找本身肯定发生在GIL下,并且任何潜在的相等性比较都肯定发生在保证是活动的对象上。但它可能仍然不安全,除非在某些情况下。在

首先,你在这里所做的更高层次的操作本质上是活泼的。如果线程1可以同时执行d['foo'] = 3del d['foo'],则没有正确的答案。这不是原子的问题,这里没有排序。在

但是,如果您在应用程序级别上确实有某种显式的排序,因此有一个正确的答案可以得到,那么只有当两个线程都具有GIL时,才能保证得到正确的答案。我想这就是你要问的,是吗?在

这在CPython中甚至是可能的,即使在那里,它也相当于保证当你试图hash或{}时,你放在dict中的任何对象都不会释放GIL,这通常很难保证。在

现在,如果另一个线程只是替换与键相关联的值,而不是更改键集呢?然后,是一个正确的答案,并且只要dict实现避免为此操作改变哈希表,它就可以并发使用。至少在2010年7月29日之前发布的CPython版本中。Alex Martelli在回答python dictionary is thread safe?时间接保证了这一点。因此,在这种受限的情况下,在CPython中和在其他实现中都是安全的,但是在依赖它之前,您应该先阅读代码。在

正如在评论中指出的,你可能最终比较你的查找值的键不一定是不可变的,所以即使另一个线程没有做任何改变键集的事情,它仍然不能绝对保证你会得到正确的答案。(您可能需要创建一个病态的密钥类型才能使其失败,但它仍然是一个合法的密钥类型。)

相关问题 更多 >