lostdong12
lostdong12

Reputation: 97

How does condition_variable work in this example?

// 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;
}

How does condition_variable work here? It calls "go()" before the threads join, so doesn't that mean no threads are waiting? And it is calling "notify_all()" in "go()", is it doing anything by notifying all?

Upvotes: 0

Views: 98

Answers (2)

eerorika
eerorika

Reputation: 238401

It calls "go()" before the threads join, so doesn't that mean no threads are waiting?

No, it does not mean that. There may be any number of threads waiting, depending on which threads have had the chance to execute and start waiting before go does. It is certainly possible - although unlikely if there are multiple hardware threads - that go notifies before any thread has started waiting but that is not a necessity.

Joining means that the thread which calls the join will wait for the thread that was called on to end, before the calling thread resumes. If go was called after joining, then the program would never finish because the threads in the array are waiting on the condition variable and the main thread is waiting for the other threads to end before setting the variable.

And it is calling "notify_all()" in "go()", is it doing anything by notifying all?

It notifies all threads that may be waiting on the condition variable. If no thread is waiting, then no thread will react to the notification.

Upvotes: 2

Caleth
Caleth

Reputation: 63019

The threads start executing on the line threads[i] = std::thread(print_id,i);

Each thread will acquire the mutex, then release it by waiting on the condition variable. This pauses the execution of that thread.

When go() is run, it wakes all the threads, and they resume executing. The th.join() calls are the main method waiting for each worker thread to be finished before the program exits.

Note that only the threads that managed to acquire the lock (and therefore proceed to waiting on cv) will be notified, the others will acquire the lock later and see ready true, bypassing cv

Upvotes: 2

Related Questions