I have a thread that is doing "work", it is supposed to report progress when conditional variable notifies it. This thread is waiting for conditional variables.
Other thread is waiting for a x amount of milliseconds and then notifies conditional variable to proceed.
I have 5 conditional variables (this is an exercise for school) and once each gets notified work progress is supposed to be reported:
Problem im having is that thread 2, the one that is supposed to notify thread 1, goes through all 5 checkPoints and notifies only once in the end. So I end up in a situation where progress is at 20% in the end and thread 1 is waiting for another notify but thread 2 has finished all notifies.
Where is flaw in my implementation of this logic? Code below:
#include <condition_variable>
#include <functional>
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
class Program {
public:
Program() {
m_progress = 0;
m_check = false;
}
bool isWorkReady() { return m_check; }
void loopWork() {
cout << "Working ... : " << endl;
work(m_cv1);
work(m_cv2);
work(m_cv3);
work(m_cv4);
work(m_cv5);
cout << "\nFinished!" << endl;
}
void work(condition_variable &cv) {
unique_lock<mutex> mlock(m_mutex);
cv.wait(mlock, bind(&Program::isWorkReady, this));
m_progress++;
cout << " ... " << m_progress * 20 << "%" << endl;
m_check = false;
}
void checkPoint(condition_variable &cv) {
lock_guard<mutex> guard(m_mutex);
cout << " < Checking >" << m_progress << endl;
this_thread::sleep_for(chrono::milliseconds(300));
m_check = true;
cv.notify_one();
}
void loopCheckPoints() {
checkPoint(m_cv1);
checkPoint(m_cv2);
checkPoint(m_cv3);
checkPoint(m_cv4);
checkPoint(m_cv5);
}
private:
mutex m_mutex;
condition_variable m_cv1, m_cv2, m_cv3, m_cv4, m_cv5;
int m_progress;
bool m_check;
};
int main() {
Program program;
thread t1(&Program::loopWork, &program);
thread t2(&Program::loopCheckPoints, &program);
t1.join();
t2.join();
return 0;
}