demo error code using unique_lock

// condition_variable example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

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();
}

int main ()
{
std::thread threads[10];
// spawn 10 threads:
for (int i=0; i<10; ++i)
threads[i] = std::thread(print_id,i);

std::cout << "10 threads ready to race...\n";
go(); // go!

for (auto& th : threads) th.join();

return 0;
}
What is the error?
sorry!

std::unique_lock<std::mutex> lck(mtx);

This statement will lock the mutex in constractor.

I miss understand the behavier with std::lock_guard.

the default lock state confused me.
> std::unique_lock<std::mutex> lck(mtx); This statement will lock the mutex in constractor.
> I miss understand the behavier with std::lock_guard

Yes.

1. The constructor of std::unique_lock<std::mutex> acquires the lock.

2. When cv.wait(lck) is executed, it atomically releases lock and blocks the thread.

3. When the thread is unblocked (with cv.notify_all()) the lock is reacquired before cv.wait(lck); returns.

4. The while loop while (!ready) is there because the thread may be unblocked spuriously.
cv.wait( lck, []{ return ready ;} ); is equivalent to while (!ready) cv.wait(lck)

Note that waiting for a std::condition_variable works only with std::unique_lock<std::mutex>

In the function go, modifying the variable ready while holding a less expensive std::lock_guard is adequate;
since the thread does not wait on a condition variable.
Topic archived. No new replies allowed.