I am currently studying Conditional variables and I am starting to get it. However on the code from here:
void print_id (int id) {
std::unique_lock<std::mutex> lck(mtx);
while (!ready) cv.wait(lck);
// ...
std::cout << "thread " << id << '\n';
}
void go() {
std::unique_lock<std::mutex> lck(mtx); <<<<<< ?
ready = true;
cv.notify_all();
}
In print_id
I understand the declaration of lck
since it will be used by cv.wait()
. In the go
function, I don't understand the purpose declaration of lck
since it is not used. I tried removing and running and it seems fine. Is it really necessary or am I missing something?
When you do
std::unique_lock<std::mutex> lck(mtx);
you create an object named lck
that call lock
on mtx
. You need this because ready
is a non-atomic variable and writing to it without synchronization is undefined behavior since you have another thread that is reading from it. Once go
ends lck
is destroyed and it automatically calls unlock
for you.
Lock guards normally aren't "used". We use them so that we can lock a mutex without having to worry about unlocking the mutex in every possible exit path. To make life easy we put that unlocking code into the destructor of an object that will be destroyed on any exit path from the function so that the mutex will always be unlocked.