So if I wanted to lock a mutex, could use mut.lock() and mut.unlock(), but the more modern way to do it is to use std::lock_guard<std::mutex> lock(myMutex);, but what if i have other code in my scope? I dont need to manually unlock lock_guard, so other code in my function will be locked instead of just doing something like:
1 2 3
ulock.lock();
// Critical section
ulock.unlock();
so if i have other code do i just manually use lock and unloack? or could i put this code between a nested scope like so:
1 2 3 4 5 6 7 8 9 10 11
void MyFunction()
{
// ... some code that doesn't need to be locked
{
std::lock_guard<std::mutex> lock(myMutex);
// Critical section
}
// ... some more code that doesn't need to be locked
}
I've never come across a reason to use nested blocks before so im not sure what to do here.
Yes, it is much recommended to use std::lock_guard for locking/unlocking a mutex, because it will always properly unlock the mutex when it goes out of scope, may it be normally or by an exception. This pattern is called "Resource acquisition is initialization" (RAII).
When manually calling lock() and unlock(), it is way to easy to do wrong, especially when exceptions may occur!
If not all code in your function requires serialization, then I think it is perfectly fine and normal to limit the scope of the std::lock_guard, by using curly brackets, to the "critical section" that actually needs serialization – exactly as shown in your example above 👍