gpt4 book ai didi

python - collections.defaultdict 是线程安全的吗?

转载 作者:太空狗 更新时间:2023-10-29 17:03:51 27 4
gpt4 key购买 nike

我根本没有在 Python 中使用过线程,并且作为一个完全陌生的人问过这个问题。

我想知道 defaultdict是线程安全的。让我解释一下:

我有

d = defaultdict(list)

默认情况下会为丢失的键创建一个列表。假设我有多个线程同时开始执行此操作:

d['key'].append('value')

最后,我应该以 ['value', 'value'] 结束。但是,如果 defaultdict 不是线程安全的,如果 thread 1 在检查 if 'key' in 后让步给 thread 2 dictd['key'] = default_factory()之前,会造成交错,另一个线程会在d['key']中创建list > 并可能附加 'value'

然后当thread 1再次执行时,它会从d['key'] = default_factory()继续执行,这将破坏现有的列表和值,我们将在 ['key'] 中结束。

我看了CPython source code for defaultdict .但是,我找不到任何锁或互斥体。我想只要有记录,它就不是线程安全的。

昨晚在 IRC 上有人说 Python 上有 GIL,所以它在概念上是线程安全的。有人说线程不应该在 Python 中完成。我很困惑。想法?

最佳答案

它是线程安全的,在这种特定情况下

了解为什么了解 Python 何时切换线程很重要。 CPython 只允许在 Python 字节码步骤之间切换线程。这就是 GIL 的用武之地;每 N 字节代码指令释放锁并可以发生线程切换。

d['key'] 代码由一个字节码 (BINARY_SUBSCR) 处理,该字节码触发 .__getitem__() 方法调用字典。

defaultdict,配置有 list 作为默认值工厂,并使用字符串值作为键,处理 dict.__getitem__() 完全 C 中的方法,并且 GIL 永远不会解锁,使dict[key] 查找线程安全。

注意那里的条件;如果您使用 不同 默认值工厂创建一个 defaultdict 实例,该实例使用 Python 代码 (lambda: [1, 2, 3]例如),所有的赌注都没有了,因为这意味着 C 代码回调到 Python 代码,并且可以在执行 lambda 函数的字节码时再次释放 GIL。这同样适用于键,当使用在 Python 代码中实现 __hash____eq__ 的对象时,可以在那里进行线程切换。接下来,如果工厂是用显式释放 GIL 的 C 代码编写的,则可能会发生线程切换,并且线程安全性不存在。

关于python - collections.defaultdict 是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17682484/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com