我需要同步不可变对象吗?
我有一个不可变的对象(一个float
),它由一个线程“写入”并由另一个线程读取。我需要同步吗?
class Foo:
def __init(self):
self._bar = None
def writeAttribute(self, newValue):
self._bar = newValue
def readAttribute(self):
return self._bar
请注意,对于同一实例,writeAttribute
和 readAttribute
是从不同线程调用的。我的理解是 readAttribute 返回一个对旧值或新值的“引用”,但不返回任何中间值。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 CPython(来自
python.org
)中,全局解释器锁(“GIL”)确保一次只有一个线程正在执行 Python 字节码。此外,线程可以在字节码之间被抢占,但不能在字节码“内部”被抢占。这意味着字节码是原子的。这意味着采用单个字节码的每个操作都是线程安全的,作为 GIL 的副作用。
考虑以下代码,
dis
模块用于查看函数的字节码:为全局
bar
分配新值仅需要一个STORE_GLOBAL 字节码。所以这应该是线程安全的,因为
bar
总是指向一个对象。它的价值永远是不确定的。值得注意的是;
float
对象是不可变的并不重要。对该对象(示例中的bar
)的引用是可变的。您希望保持定义和明确的就是该引用。其次,我建议您使用 @property 装饰器。它被认为更Pythonic。
编辑
另请参阅常见问题解答:什么类型的全局值突变是线程安全的?
Edit2
当然:当有疑问时,使用例如
Lock.
In CPython (the one from
python.org
) the Global Interpreter Lock ("GIL") ensures that only one thread at a time is executing Python bytecodes. Also, threads can be preempted in between bytecodes, but not "inside" them. That means bytecodes are atomic.That means that every action that takes a single bytecode is thread-safe as a side-effect of the GIL.
Consider the following code, were the
dis
module is used to see bytecodes for a function:Assigning a new value to the global
bar
takes only a singleSTORE_GLOBAL
bytecode. So that should be thread-safe, in the sense thatbar
always points to an object. Its value is never undetermined.Of note; it doesn't matter that a
float
object is immutable. The reference to that object (bar
in the example) is mutable. It is that reference that you want to keep defined and unambiguous.Second, instead of a getter/setter method in your
class Foo
I would propose that you use @property decorator. It is considered more Pythonic.Edit
See also the FAQ: What kinds of global value mutation are thread-safe?
Edit2
Of course: when in doubt, use e.g. a
Lock
.