我想知道 Java 的“volatile”的等价物,并找到了这个答案。相当于 Python 中的 Java volatile这(基本上)说,由于 GIL,至少在 cpython 中,所有东西在 python 中都是有效的。这是有道理的,一切都被 GIL 锁定,没有内存障碍需要担心,等等。但如果这是由规范记录和保证的,我会更高兴,而不是让它成为 cpython 目前碰巧的方式的结果实施的。因为,假设我希望一个线程发布数据而其他线程读取它,所以我可以选择这样的东西:class XFaster: def __init__(self): self._x = 0 def set_x(self, x): self._x = x def get_x(self, x): return self._xclass XSafer: def __init__(self): self._x = 0 self._lock = threading.Lock() def set_x(self, x): with self._lock: self._x = x def get_x(self, x): with self._lock: return self._x我宁愿使用XFaster甚至根本不使用 getter 和 setter。但我也想可靠地、“正确地”做事。是否有一些官方文件说这是可以的?比如说将值放入 adict或附加到 a怎么样list?换句话说,是否有一种系统的、有记录的方法来确定我可以做什么而无需threading.Lock(无需深入挖掘dis或类似的东西)?并且最好以不会破坏未来 python 版本的方式。关于编辑:我感谢评论中的知情讨论。但我真正想要的是一些保证以下内容的规范:如果我执行这样的事情:# in the beginningx.a == foo# then two threads start# thread 1:x.a = bar# thread 2do_something_with(x.a)我想确定:当线程 2 读取时,x.a它读取foo或者bar如果线程 2 中的读取发生在物理上晚于线程 1 中的分配,那么它实际上读取bar以下是一些我不想发生的事情:线程被安排在不同的处理器上,x.a=bar线程 1 的分配对线程 2 不可见x.__dict__正在重新散列,因此线程 2 读取垃圾ETC
1 回答
湖上湖
TA贡献2003条经验 获得超2个赞
CPython 保证它自己的数据结构是线程安全的,不会损坏。这并不意味着任何自定义数据结构或代码都是无竞争的。
GIL 的目的是保护 CPython 的数据结构免受损坏。人们可以相信内部状态是线程安全的。
全局解释器锁(Python 文档 – 词汇表)
CPython 解释器用于确保一次只有一个线程执行 Python 字节码的机制。这通过使对象模型(包括关键的内置类型,如 dict)对并发访问隐式安全来简化 CPython 实现。[...]
这也意味着跨线程更改的正确可见性。
然而,这并不意味着任何孤立的语句或表达式都是原子的:几乎任何语句或表达式都可以调用多个字节码指令。因此,GIL 明确不为这些情况提供原子性。
具体来说,一条语句x.a=bar
可以通过调用 setterobject.__setattr__
或描述符协议来执行任意多条字节码指令。它至少执行三个字节码指令,用于bar
查找、x
查找和a
赋值。
因此,Python保证可见性/一致性,但不提供针对竞争条件的保证。如果一个对象同时发生变化,则必须对其进行同步以确保正确性。
添加回答
举报
0/150
提交
取消