I'm somewhat new to threading and I'm trying to understand how it works in C++11. The professor in my class gave us this sample code to demonstrate the use of a mutex:
#include <list>
#include <mutex>
#include <algorithm>
std::list<int> some_list; // A data structure accessed by multiple threads
std::mutex some_mutex; // This lock will prevent concurrent access to the shared data structure
void
add_to_list(int new_value) {
std::lock_guard<std::mutex> guard(some_mutex); // Since I am going to access the shared data struct, acquire the lock
some_list.push_back(new_value); // Now it is safe to use some_list. RAII automatically releases lock at end of function }
}
bool
list_contains(int value_to_find) {
std::lock_guard<std::mutex> guard(some_mutex); // Must get lock every time I access some_list return
std::find (some_list.begin(),some_list.end(),value_to_find) != some_list.end();
}
I think the code is somewhat self-explanatory but I had some specific questions.
This is not a question about the scope (global or otherwise) of a "mutex object", it is a question about what scope of variables are "locked" by a mutex. I believe the answer to be that a mutex locks access to all variables, ie; all global and locally scoped variables.
The mutex is used to protect the condition variable itself. That's why you need it locked before you do a wait. The wait will "atomically" unlock the mutex, allowing others access to the condition variable (for signalling).
The associated mutex is used to ensure that a condition can be checked atomically, and that the thread can block on the associated condition variable without missing either a change to the condition or a signal that the condition has changed.
Unless you use a mutex or another form of memory barrier. So if you want correct behavior, you don't need a mutex as such, and it's no problem if another thread writes to the variable while you're reading it.
The mutex is associated with the list, but this association is completely manual -- the compiler and runtime library do not know that the two are associated. The association exists entirely in your documentation and in your head, and you are responsible for ensuring that any thread which accesses the list locks/acquires the mutex first.
Whenever a mutex is used, the thread which locks/acquires the mutex will halt (the term is actually block) until no other thread owns the mutex. Threads which are not using the mutex will be unaffected.
You are responsible for ensuring that only the threads which access the list lock/acquire the mutex, and you are also responsible for ensuring that all of the threads which access the list lock/acquire the mutex. Again, only those threads can block waiting for the mutex.
The same object goes by a number of different names: "mutex", "lock", or "critical section". The guard uses RAII to lock/acquire the mutex.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With