vendredi 27 février 2015

Const means Thread-safe?


I was put onto this video:


http://ift.tt/10EJcR6


By http://ift.tt/1wixeZv


Because I asked this question:


http://ift.tt/1vBCFrl


Marking a class std::mutex as mutable is the right answer to my original question and the video is an excellent and enjoyable discussion around that. I am grateful to glampert.


However I disagree with the premise of the talk that "const == thread-safe" (see time-point 16:00).


Below is my proposal for how we should interpret const in a multi-threaded world. It's not as simple as Herb's proposal but (let's face it) if you think any of the answers in multi-threading are simple you've completely failed to grasp the challenge of multi-threading.


Comments please. What do you think const means for multi-threaded programs? Has its meaning fundamentally changed?



const means logically unmodified by dereferences through the const reference in question.


Multi-threading footnote #1: In objects that form part of the shared state of a multi-threaded program “logically unmodified” will mean “logically const member functions only perform reads on the object” and so any implementation that actually performs writes (such as cached values, instrumentation and even employs synchronization mutexes) needs to adequately make them thread-safe to maintain the ‘logical’ appearance of ‘only reads’.


Single-threading footnote : Of course even in a single threaded application const is by no means a guarantee that an object won’t change during the lifetime of a given const reference. There may be non-const references (aliases) and even a single threaded program might use to modify an object which has one or more const references.


Multi-threaded footnote #2: That lack of guarantee that an object will not be modified just because there is a const reference to it is true in spades for multi-threaded applications. So in many senses – no change there.



I think my greatest concern is that through I am sure Herb Sutter would confirm them as dreadful fallacies, I fear that reading const as ‘thread-safe’ leads too easily to:



  1. The fallacy that adding std::lock_guard guard(this->mutex) to the start of all methods and the destructor of a class somehow make any use of it ‘thread-safe’.

  2. The fallacy that if you only call const methods on a class your application has a thread-safe guarantee and you can complain to the implementer if not.

  3. Finally, the fallacy that if you don’t modify any mutable members and don’t cast away const anywhere you don’t need to worry about thread-safety because (apparently) “const means thread-safe”.


Fallacy 1 is best exemplified by supposing you can get any sense iterating through a collection that is being modified by another thread just because you know the methods are lock-guarded.


Fallacy 2 pushes a potentially onerous (and even impossible) burden on to implementers who can (of course) add lock-guards to all their methods but may (at best) be wasting time and (at worst) just setting you up for fallacy 1.


Fallacy 3 is the fallacy that thread-safety is all about competing for simultaneous access. Memory caching however means that to obtain a coherent state within a const method there may still be a requirement to ensure some kind of memory barrier has been performed (e.g. at least “acquire”).





Aucun commentaire:

Enregistrer un commentaire