Redis1001
Redis1001

Reputation: 157

notify_one() in c++ thread waking up more than one thread

Hello I have the following code:

// 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> lock(mtx);
  while (!ready) cv.wait(lock);
  // ...
  std::cout << "thread " << id << std::endl;
}

void go() {
  std::unique_lock<std::mutex> lock(mtx);
  ready = true;
  cv.notify_one();
}

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..." << std::endl;
  go();                       // go!

  for (auto& th : threads) th.join();
  std::cout << "Finished!" << std::endl;

  return 0;
}

And this is the output:

10 threads ready to race...
thread 9
thread 0

My expectation is that by calling notify_one(), only one thread will be notified and I will reach a deadlock. But in this case, two threads were notified before reching deadlock. What am I missing here? Thank you

Upvotes: 3

Views: 2334

Answers (2)

Kane
Kane

Reputation: 6250

It might be that not all threads are started when you call go(). Then this might happen:

  1. Nine threads are running and waiting for a condition variable.
  2. You call go() which sets ready to true and notifies thread zero.
  3. Tenth thread is started, it sees ready is true and does not wait for the condition variable.

Upvotes: 5

Tatsuyuki Ishi
Tatsuyuki Ishi

Reputation: 4031

You should not count on the amount of notified threads. notify_one wakes up "at least one, if waiting threads exist".

The C++ standard allows spurious wakeups, which means a thread woken up without a notification.

Instead, check the variable you protect in the mutex. You may consider adding a counter if you want the exact-counted notification behavior.

Upvotes: 3

Related Questions