首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >collections.defaultdict线程安全吗?

collections.defaultdict线程安全吗?
EN

Stack Overflow用户
提问于 2013-07-16 16:49:53
回答 1查看 4.2K关注 0票数 25

我根本没有用Python处理过线程,而是作为一个完全陌生的人问过这个问题。

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

我有过

代码语言:javascript
运行
复制
d = defaultdict(list)

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

代码语言:javascript
运行
复制
d['key'].append('value')

最后,我应该和['value', 'value']一起结束。但是,如果defaultdict不是线程安全的,如果线程1在检查if 'key' in dictd['key'] = default_factory()之前向线程2输出,则会导致交织,而另一个线程可能会在d['key']中创建列表并追加'value'

然后,当线程1再次执行时,它将从d['key'] = default_factory()继续,这将销毁现有的列表和值,我们将以['key']结束。

我看了看默认情况下的CPython源代码。然而,我找不到任何锁或互斥。我想只要它被记录下来,它就不是线程安全的。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-16 16:54:06

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

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

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

一个defaultdict (配置为list作为默认值工厂,并使用字符串值作为键)完全以C语言处理dict.__getitem__()方法,而GIL从未被解锁,从而使dict[key]查找线程安全。

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

票数 32
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17682484

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档