1

I have a queue of worker thread IDs in C++, and a coordinator thread wakes each thread in order. The woken thread then interacts with the coordinator thread to perform some work. Once done, the coordinator wakes the next thread.

I am considering two approaches to implement this:

  1. Separate Condition Variables: Each worker thread has its own std::condition_variable, stored in a queue along with its thread ID. The coordinator signals the respective condition variable to wake up a specific thread.
  2. Single Condition Variable: All worker threads wait on a shared std::condition_variable, using a predicate to check if their ID matches the one chosen by the coordinator.

Approach 2: Using a Single Condition Variable

Coordinator Thread:

while (true) {
  {
    std::lock_guard<std::mutex> lock(mtx);
    id_chosen_by_coordinator = workerThreads.front();
    workerThreads.pop();
  }
  cv.notify_all();  // Wake up all worker threads, but only one will proceed
  ...
}

Worker Thread:

std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []() { return myid == id_chosen_by_coordinator; });
...

Which of these approaches is preferable in terms of efficiency and correctness? Are there potential pitfalls with the single condition variable approach, such as unnecessary wake-ups or race conditions?

4
  • 1
    I wouldn't even have a coordinator, I just would use a threadpool where all threads have access to the same queue which you manage with one condition variable. Commented Feb 13 at 7:53
  • 1
    "Are there potential pitfalls with the single condition variable approach, such as unnecessary wake-ups" - spurious wake-up is always a possibility with condition variables. You always need to handle that. Commented Feb 13 at 8:10
  • Sounds like there might never be more than one thread doing any work at any given moment in time. If that's true, then why use threads at all? Why not just let the "coordinator" do all of the work? Commented Feb 13 at 19:22
  • @JesperJuhl said, "spurious wake-up is always a possibility." That's true, but that's why you're using the two-argument form of cv.wait. If the thread is awakened "spuriously," then your condition, myid==id_chosen_by_coordinator will be false, and the wait will go back to sleep and wait again for the real notification. The way you wrote it, the wait will not return until myid==id_chosen_by_coordinator actually is true. Commented Feb 13 at 19:28

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.