【发布时间】:2021-02-02 03:57:11
【问题描述】:
CPython 中用于确保迭代线程安全的一个常见习惯用法是使用tuple()。
例如 - tuple(dict.items()) 在 CPython 中保证是线程安全的,即使项目被不同的线程删除。
这是因为解释器在运行这些 C 函数时不运行 eval 循环并且不释放 GIL。我已经测试过了,效果很好。
但是,tuple(reversed(dict.items())) 似乎不是线程安全的,我不明白为什么。它没有运行任何 Python 函数,也没有显式释放 GIL。如果在 dict 在不同的线程上运行时删除密钥,为什么我仍然会收到错误消息?
【问题讨论】:
-
@juanpa.arrivillaga 我不确定错误是否是正确的术语,因为 GIL 本身并没有给你这种保证,而且你在技术上应该使用锁。然而这是出乎意料的,我想知道为什么它会这样工作。
-
也许是监督?
-
当然,如果您需要此类数据结构上的线程安全,您应该使用显式锁,即使在给定的 Python 版本中您可以摆脱它。请记住,线程并发的这种不可预测性是支持现代单线程异步的最佳论据之一。即使对于“元组”构造函数,这种“线程安全”也应该被视为实现细节。
-
@jsbueno ofc 它应该算作一个实现细节,但又为什么 gil 会被释放?
标签: python thread-safety cpython python-internals gil