Search code examples
c++multithreadingcondition-variable

Not all threads notified of condition_variable.notify_all()


I have following scenario:

condition_variable cv;
mutex mut;

// Thread 1:
void run() {
    while (true) {
        mut.lock();
        // create_some_data();
        mut.unlock();
        cv.notify_all();        
    }
}

// Thread 2
void thread2() {
    mutex lockMutex;
    unique_lock<mutex> lock(lockMutex);
    while (running) {
        cv.wait(lock);
        mut.lock();
        // copy data
        mut.unlock();
        // process data
    }
}

// Thread 3, 4... - same as Thread 2

I run thread 1 all the time to get new data. Other threads wait with condition_variable until new data is available, then copy it and do some work on it. Work perfomed by threads differs in time needed to finish, the idea is that threads will get new data only when they finished with the old one. Data got in meantime is allowed to be "missed". I don't use shared mutex (only to access data) because I don't want threads to depend on each other.

Above code works fine on Windows, but now I run it on Ubuntu and I noticed that only one thread is being notified when notify_all() is called and the other ones just hangs on wait(). Why is that? Does Linux require different approach for using condition_variable?


Solution

  • It's working by luck.

    The mutex and the condition variable are two parts of the same construct. You can't mix and match mutexes and cvs.

    try this:

    void thread2() {
        unique_lock<mutex> lock(mut); // use the global mutex
        while (running) {
            cv.wait(lock);
            // mutex is already locked here
            // test condition. wakeups can be spurious
            // copy data
            lock.unlock();
            // process data
    
            lock.lock();
        }
    }