4

This is a question about the C++ standard. I only have access to the draft standard so if this is different in the official one, I apologise. Also if I've misunderstood how this works please feel free to correct me.

Assume I have two threads, one writing to a string and one making a copy of the contents of that string. I protect access to them using a std::mutex myMutex; I know you should in general use the RAII classes for locks, I just used lock and unlock explicitly to make the example more explicit.

// Global variable
std::string message;
std::mutex myMutex;

// Thread one
myMutex.lock();
message = "Hello";
myMutex.unlock();

// Thread two
myMutex.lock();
std::string copy = message;
myMutex.unlock();

My understanding is that in order for this to work reliably between threads, thread one must perform a Release operation after setting the string, and thead two must perform an Acquire before reading the string.

Reading the draft standard for C++11 I can't see anything that states that std::mutex does this, although it's fairly obvious that it's expected to or the mutex would be useless for anything.

Can someone point me to the relevent section to look at? The wording in the standard is often not exactly clear to a casual reader :)

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
jcoder
  • 29,554
  • 19
  • 87
  • 130
  • 1
    30.4.1.2-5 ff. not strong enough? – PlasmaHH Nov 13 '12 at 11:05
  • That appears to only say that the class shall provide lock and unlock functions which will behave as atomic operations. Without giving any more specific information – jcoder Nov 13 '12 at 11:10
  • Are you basically asking what the difference between "lock" and "acquire", as well as between "unlock" and "release" is? My understanding is that _locking_ (the Standard also uses the word _own_) implies acquiring the mutex, and _unlocking_ it implies releasing the mutex. – jogojapan Nov 13 '12 at 11:12
  • 1
    I was looking for somewhere in the standard that required that to be true. The link you gave and the comments others linked to do that, thanks :) – jcoder Nov 13 '12 at 11:21

1 Answers1

9

Per 30.4.1.2p11,

Synchronization: Prior unlock() operations on the same object shall synchronize with (1.10) [m.lock()].

Under 1.10p5,

[...] For example, a call that acquires a mutex will perform an acquire operation on the locations comprising the mutex. Correspondingly, a call that releases the same mutex will perform a release operation on those same locations. Informally, performing a release operation on A forces prior side effects on other memory locations to become visible to other threads that later perform a consume or an acquire operation on A. [...]

ecatmur
  • 152,476
  • 27
  • 293
  • 366