我在想Java中的“volatile”在Python中的等价物是什么,结果找到了这个答案。
An equivalent to Java volatile in Python
该答案(基本上)表示,在CPython中,所有东西都是有效的,因为有全局解释器锁(GIL)。 这很有道理,因为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._x
class 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。但我也想要可靠和“正确”的操作。是否有一些官方文档表明这是可以的?比如将值放入dict
或向list
追加内容?
换句话说,是否有一种系统化的、有文档支持的方法来确定我可以在没有threading.Lock
的情况下做什么(而不需要挖掘dis
之类的东西)?并且最好不会在未来的Python版本中出现问题。
编辑:感谢评论区中的讨论。但我真正想要的是一些规范,保证以下内容:
如果我执行类似于以下的代码:
# in the beginning
x.a == foo
# then two threads start
# thread 1:
x.a = bar
# thread 2
do_something_with(x.a)
我希望确保:
- 当线程2读取
x.a
时,它读取的是foo
或bar
之一。 - 如果线程2中的读取在物理上晚于线程1中的赋值发生,则实际上读取的是
bar
。
以下是我不希望发生的情况:
- 线程被调度到不同的处理器上,并且线程1中的赋值
x.a=bar
对线程2不可见。 x.__dict__
正在重新哈希过程中,因此线程2读取了垃圾数据。- 等等
a,b=c,d
是一个单独的语句吗?)。但也仅仅因为它们不同时发生,并不意味着线程 A 看到的内存将反映线程 B 中发生的所有事情,比如操作系统在不同处理器上安排线程的情况。它应该,而且几乎肯定会工作,但如果 python.org 上有一些明确说明的文档,那将是很好的。 - mripset_x
,并从其他线程使用XFaster
调用get_x
,或者我需要使用XSafer
来确保我不会遇到任何问题。而且我想在python.org上阅读相关内容,而不是在某个博客文章上。 - mrip