In the code below, which I have tried to make minimially verifiable, runs fine and does what it should (print 1,2,3 in order no matter which order I pass in threads). However, if I change m1 to m2 in the line that I have commented in the function third, this code crashes with the message "terminated without an active exception". Why can't I use the same condition variable to lock on two different mutex's at the same time?
#include <functional> #include <mutex> #include <condition_variable> #include <future> #include <iostream> void printFirst() { cout << "1"; } void printSecond() { cout << "2"; } void printThird() { cout << "3"; } struct test { condition_variable c, c2; int count = 0; mutex m1,m2; void first(function<void()> printFirst) { printFirst(); count++; c.notify_all(); } void second(function<void()> printSecond) { unique_lock<mutex> sL1(m1); c.wait(sL1,[&]{return count>=1;}); printSecond(); count+=1; c.notify_all(); } void third(function<void()> printThird) { unique_lock<mutex> sL2(m1); //If I make m1, m2, this code crashes c.wait(sL2,[&]{return count>=2;}); printThird(); } }; int main() { test t; function<void()> printFirstN =[&](){ t.first(printFirst);}; function<void()> printSecondN=[&](){ t.second(printSecond);}; function<void()> printThirdN=[&](){ t.third(printThird);}; std::thread t1(printFirstN); std::thread t2( printThirdN); std::thread t3( printSecondN); t1.join(); t2.join(); t3.join(); }