While I agree with this for cases where you would want to use another value that either hasn’t been sent yet, or has been written to where it will be read from, this case seems different to me.
Here the code just wanted that the thread will eventually read the value true (in whatever iteration of the while loop), so I am wondering a bit if this advice is just people wanting to make extra sure to make it well defined for (other) common cases.
This answer looks to me more like this answer: Why is volatile not considered useful in multithreaded C or C++ programming? - Stack Overflow
In this particular case we don’t actually care about the second point, which makes the statement that:
The problem with volatile
in a multithreaded context is that it doesn’t provide all the guarantees we need. It does have a few properties we need, but not all of them, so we can’t rely on volatile
alone.
untrue for this case, because we don’t read any data, we just want the thread to quit eventually.
But playing devil’s advocate: Isn’t this case essentially receiving a message from memory (eventually) that it is ok for that thread to shutdown now? Thus it is as if this was a received Memory Mapped Input.
Only when you also want to read some value that was created by that thread you then need something to syncronize/order before then accessing whatever value is being shared.
I wouldn’t be surprised if this would cause the thread to stay alive a little bit longer then if it syncronized on the value with .monotonic
, but if the code doesn’t care if the shutdown happens a bit later, then you could argue that using more syncronization than necessary for the entire run time, is worse than it staying around for a bit longer (caused by reordering we don’t have to care about as long as there aren’t any reads of other data being done).
I think (and I might be wrong, because I just have a bit of knowledge fragments assembled from various things I read or listened to) that a more interesting question might be: Could using volatile (which isn’t a locking mechanism) instead of other syncronization primitives cause a bigger performance bottle neck?
or said another way: Could using a monotonic lock be actually faster than forcing the thread to go all the way out to main memory all the time?
I don’t really know, but my suspicion is that clever architectures might be really good at avoiding contention and optimizing locks and the going to main-memory is such a big slowdown that can’t be avoided once you have forced it, that the better reason for not using volatile might be simply that it causes so much slowness, that you are better off betting on another horse, which would be just using a syncronization mechanism (what ever you can get away with).
Just to repeat, I am not an expert on this, if I am wrong I want to know why.