std::lock_guard

Instead of littering your code with try/catch blocks to prevent deadlock, which assumes the programmer is even capable of determining every possible scenario where this could occur without making a mistake, C++ provides an std::lock_guard object to simplify the use of the std::mutex object.

For example, consider the following code:

#include <mutex>
#include <thread>
#include <iostream>

std::mutex m{};

void foo()
{
static std::string msg{"The answer is: 42 "};

while(true) {
std::lock_guard lock(m);
for (const auto &c : msg) {
std::clog << c;
}
}
}

int main(void)
{
std::thread t1{foo};
std::thread t2{foo};

t1.join();
t2.join();

// Never reached
return 0;
}

When executed, we see the following:

As shown in the preceding example, std::lock_guard is used when we would normally call lock() on the mutex. std::lock_guard calls the lock() function on the mutex when it is created and then calls unlock() on the mutex when it is destroyed (an idiom called Resource Acquisition Is Initialization or RAII). No matter how the function returns (either from a normal return or an exception), the mutex will always be released, ensuring deadlock is not possible, preventing the programmer from having to accurately determine every possible scenario where the function could return.

Although std::lock_guard is capable of preventing deadlock in cases where unlock() is never called, it is not capable of preventing deadlock from occurring in cases where lock() is called by the same thread more than once prior to unlock() being called. To handle this scenario, C++ provides std::recursive_mutex.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset