python列表是线程安全的吗,扩展Python列表(例如l+=[1])是否保证线程安全?

没有一个快乐的答案;—)这个答案。其中任何一个都没有保证,您可以简单地通过注意Python参考手册对原子性没有保证来确认这一点。在

在CPython中,这是一个语用学的问题。正如effbot文章中的一个删节部分所说In theory, this means an exact accounting requires an exact understanding of the PVM [Python Virtual Machine] bytecode implementation.

这是事实。CPython专家知道L += [x]是原子的,因为他们知道以下所有内容:+=编译为INPLACE_ADD字节码。在

list对象的INPLACE_ADD的实现完全是用C编写的(执行路径上没有Python代码,因此GIL不能在字节码之间释放。在

在listobject.c中,INPLACE_ADD的实现是函数list_inplace_concat(),在其执行过程中也不需要执行任何用户Python代码(如果执行了,GIL可能再次被释放)。在

这些听起来可能难以置信地难以直截了当,但对于拥有efbot的CPython内部知识的人来说(在他写那篇文章的时候),事实并非如此。事实上,鉴于知识的深度,这一切都是显而易见的;-)

因此,作为语用学的一个问题,CPython的专家们总是自由地依赖于“看起来像原子的操作应该是原子的”,这也指导了一些语言决策。例如,effbot的列表中缺少一个操作(在他写了那篇文章之后添加到语言中):x = D.pop(y) # or ...

x = D.pop(y, default)

(当时)支持添加dict.pop()的一个论据正是,显而易见的C实现将是原子的,而在使用中(当时)的替代方法是:

^{pr2}$

was不是原子的(检索和删除是通过不同的字节码完成的,因此线程可以在它们之间切换)。在

但是文档从来没有说过原子是原子的,而且永远不会。这是一种“同意的成年人”的事情:如果你有足够的专家在知情的情况下利用这一点,你不需要牵手。如果你不够专业,那么effbot文章的最后一句话适用:When in doubt, use a mutex!

出于实际需要,核心开发人员永远不会破坏CPython中efffbot示例(或D.pop()或{})的原子性。不过,其他实现根本没有义务模仿这些实用的选择。实际上,由于这些情况下的原子性依赖于CPython特定形式的字节码,再加上CPython使用只能在字节码之间释放的全局解释器锁,可能会成为其他实现模仿它们的真正痛苦。在

你永远不知道:未来的CPython版本也可能会删除GIL!我对此表示怀疑,但理论上是可能的。但如果发生这种情况,我敢打赌保留GIL的并行版本也会得到维护,因为很多代码(尤其是用C编写的扩展模块)也依赖GIL来保证线程安全。在

值得一提的是:When in doubt, use a mutex!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值