c++multithreadingmutexcondition-variable

(c++ thread and condition_variable) Could this program never end forever?


I think the source code below may not end forever.

Assume that all waiter threads have entered the wait state. After that, waker call notify_all()

One thread, t1, wakes up and does something. And Other threads wake up while working, but mutex is occupied by t1, so it returns to the wait state.

That other thread falls asleep forever, so this program doesn't end.

#include <chrono>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <vector>

using namespace std;

mutex m;
condition_variable cv;

bool isStop = false;

void waiter()
{
    unique_lock<mutex> ul(m);
    cv.wait(ul, []() { return isStop; });

    // ...do something...
}

void waker()
{
    this_thread::sleep_for(chrono::seconds(1));

    unique_lock<mutex> ul(m);
    isStop = true;
    ul.unlock();

    cv.notify_all();
}

void main()
{
    vector<thread> ts;
    for (int i = 0; i < 100; ++i)
        ts.emplace_back(waiter);

    thread w(waker);

    for (auto& t : ts)
        t.join();
    w.join();
}

so I think that waiter function need to Unlock and notify

void waiter()
{
    unique_lock<mutex> ul(m);
    cv.wait(ul, []() { return isStop; });

    // ...do something...

    ul.unlock();
    cv.notify_all();
}

Do you think I'm right?


Solution

  • The original code is correct. When you call notify_all all waiting threads are notified, they'll all attempt to re-aquire the mutex, check the predicate, then continue. This might take a while as only one thread can aquire the mutex at a time but it's guaranteed that all threads will eventually be woken up once the mutex is released. If the thread can't immediately aquire the mutex it'll simply block on aquiring the mutex, it won't re-enter the waiting state without checking the predicate first.