python - 检查字典中的键是原子操作吗?

标签 python

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

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

最佳答案

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

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

如果您正在使用 CPython,它在 in 的意义上是原子的是单个字节码 op ( COMPARE_OP 6 ),并且在可能更有用的意义上,实际的哈希表查找本身肯定发生在 GIL 下,并且任何潜在的相等比较肯定发生在保证存活的对象上。但它可能仍然不安全,除非在某些条件下。

首先,您在这里进行的高级操作本质上是活泼的。如果线程 1 可以做 d['foo'] = 3del d['foo']同时线程 0 正在调用 'foo' in d , 没有正确的答案。这不是原子与否的问题——这里没有顺序。

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

这甚至只有在 CPython 中才有可能——即使在 CPython 中,这也相当于保证您从未将任何对象放入 dict 中。当您尝试 hash 时可能会释放 GIL或 ==它,这通常很难保证。

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

正如评论中所指出的,您可能最终将查找值与其进行比较的键不能保证是不可变的,因此即使另一个线程没有做任何改变键集的事情,它也是 仍然不能绝对保证您会得到正确答案。 (您可能必须设计一个病态的 key 类型才能使其失败,但它仍然是一个合法的 key 类型。)

关于python - 检查字典中的键是原子操作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14077688/

相关文章:

python - Dask - 如何使用 apply 将系列连接到 DataFrame 中?

Python对多个列表中的索引、键进行二次排序列表

python - 隐秘的 Django CMS 安装错误 - 可能是什么原因导致此错误?

python - BeautifulSoup 解析的问题

python - peewee 原始查询不适用于WITH 语句

python - 将 numpy 数组绘制到 QWidget 中时出现问题

python - 创建保存列名和另一个数据框的相应值的 df

python - 我无法在 docker 中安装 opencv-contrib-python

c# - 如何将 Asp.net 页面与 Python 项目集成?

Python:如何知道我 append 文本的文件是否存在或刚刚创建?