David
David

Reputation: 28178

Control multithreaded flow with condition_variable

I haven't wrapped my head around the C++11 multithreading stuff yet, but I'm trying to have multiple threads wait until some event on the main thread and then all continue at once (processing what happened), and wait again when they're done processing... looping until they're shut down. Below isn't exactly that - it's a simpler reproduction of my problem:

std::mutex mutex;
std::condition_variable cv;

std::thread thread1([&](){ std::unique_lock<std::mutex> lock(mutex); cv.wait(lock);  std::cout << "GO1!\n"; });
std::thread thread2([&](){ std::unique_lock<std::mutex> lock(mutex); cv.wait(lock);  std::cout << "GO2!\n"; });

cv.notify_all(); // Something happened - the threads can now process it

thread1.join();
thread2.join();

This works... unless I stop on some breakpoints and slow things down. When I do that I see Go1! and then hang, waiting for thread2's cv.wait. What wrong?

Maybe I shouldn't be using a condition variable anyway... there isn't any condition around the wait, nor is there data that needs protecting with a mutex. What should I do instead?

Upvotes: 7

Views: 2521

Answers (1)

Nemo
Nemo

Reputation: 71525

You are on the right track...

Just add a Boolean (protected by the mutex, indicated by the condition variable) that means "go":

std::mutex mutex;
std::condition_variable cv;
bool go = false;

std::thread thread1([&](){ std::unique_lock<std::mutex> lock(mutex); while (!go) cv.wait(lock);  std::cout << "GO1!\n"; });
std::thread thread2([&](){ std::unique_lock<std::mutex> lock(mutex); while (!go) cv.wait(lock);  std::cout << "GO2!\n"; });

{
    std::unique_lock<std::mutex> lock(mutex);
    go = true;
    cv.notify_all(); // Something happened - the threads can now process it
}

thread1.join();
thread2.join();

Upvotes: 5

Related Questions