I was asked to implement a program during an interview which spawns 2 threads taking a given input vector, one thread is responsible for only printing the even elements of the vector, and the other the odd elements. This is how I implemented the code -
std::mutex mu_vec;
std::condition_variable m_cv;
bool odd = true;
void print_odd(const std::vector<int>& vals, int &id){
while(true){
std::unique_lock sl(mu_vec);
m_cv.wait(sl, []{return odd; });
if(id >= vals.size()){
sl.unlock();
break;
}
if(vals[id] & 1){
std::cout << vals[id] << "\t";
id++;
}
else{
odd = false;
sl.unlock();
m_cv.notify_one();
}
}
}
void print_even(const std::vector<int>& vals, int &id){
while(true){
std::unique_lock sl(mu_vec);
m_cv.wait(sl, []{return !odd; });
if(id >= vals.size()){
sl.unlock();
break;
}
if((vals[id] & 1) == 0){
std::cout << vals[id] << "\t";
id++;
}
else{
odd = true;
sl.unlock();
m_cv.notify_one();
}
}
}
int main(){
std::vector<int> vals{5, 10, 4, 7, 1, 6};
int id = 0;
std::jthread odd_printer(print_odd, std::cref(vals), std::ref(id));
std::jthread eve_printer(print_even, std::cref(vals), std::ref(id));
return 0;
}
I tried debugging with using print statements within both print_odd
and print_even
functions but the program is showing no stdout and executing the code just hangs indefinitely.
Please suggest how do I debug further or what is the problem in the current program.
You are not seeing any output because the output is line-buffered and you never write a '\n'
. Just replace the "\t"
with a '\n'
and you will see that output is written but the threads hang afterwards. A debugger should show you where each thread hangs.
From looking at it, your condition variable wait condition does not check that the sequence has been fully processed. Threads should stop waiting when the id
reaches the end of the vector. Something like this:
m_cv.wait(sl, [&]{return odd || id >= vals.size(); });
if(id >= vals.size()){
sl.unlock();
m_cv.notify_one();
break;
}
and the same for the other thread.
There are other quality issues (such as using int
to index a vector
instead of using std::size_t
) and I think there are easier ways to implement this code, but that should solve the issue.