Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Release and Acquire with std::mutex

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 :)

like image 858
jcoder Avatar asked Feb 18 '23 12:02

jcoder


1 Answers

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. [...]

like image 171
ecatmur Avatar answered Feb 27 '23 18:02

ecatmur