I was wondering about the equivalent of Java's "volatile", and found this answer.
An equivalent to Java volatile in Python
Which (basically) says that everything is effectively volatile in python, at least in cpython, because of the GIL. Which makes sense, everything is locked by the GIL, no memory barriers to worry about, etc. But I would be happier if this were documented and guaranteed by specification, rather than have it be a result of the way that cpython happens to currently be implemented.
Because, say I want one thread to post data and others to read it, so I can choose something like this:
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
I'd rather go with XFaster or even not use a getter and setter at all. But I also want to do things reliably and "correctly". Is there some official documentation that says this is OK? What about say putting a value in a dict or appending to a list?
In other words, is there a systematic, documented way of determining what I can do without a threading.Lock (without digging through dis or anything like that)? And also preferably in a way that won't break with a future python release.
On edit: I appreciate the informed discussion in comments. But what I would really want is some specification that guarantees the following:
If I execute something like this:
# in the beginning
x.a == foo
# then two threads start
# thread 1:
x.a = bar
# thread 2
do_something_with(x.a)
I want to be sure that:
- when thread 2 reads
x.ait reads eitherfooorbar - if the read in thread 2 occurs physically later than the assignment in thread 1, then it actually reads
bar
Here are some things I want not to happen:
- the threads get scheduled on different processors, and the assignment
x.a=barfrom thread 1 isn't visible to the thread 2 x.__dict__is in the middle of being re-hashed and so thread 2 reads garbage- etc