我被要求在面试期间实现一个程序,该程序生成 2 个线程,采用给定的输入向量,一个线程负责仅打印向量的偶数元素,另一个线程负责打印奇数元素。这就是我实现代码的方式 -
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;
}
我尝试在
print_odd
和 print_even
函数中使用 print 语句进行调试,但程序没有显示标准输出,并且执行代码只是无限期地挂起。
请建议我如何进一步调试或者当前程序有什么问题。
您没有看到任何输出,因为输出是行缓冲的,并且您从不写
'\n'
。只需将 "\t"
替换为 '\n'
,您将看到输出已写入,但线程随后挂起。调试器应该向您显示每个线程挂起的位置。
从观察来看,您的条件变量等待条件不会检查序列是否已完全处理。当
id
到达向量末尾时,线程应停止等待。像这样的东西:
m_cv.wait(sl, [&]{return odd || id >= vals.size(); });
if(id >= vals.size()){
sl.unlock();
m_cv.notify_one();
break;
}
其他线程也一样。
还有其他质量问题(例如使用
int
来索引 vector
而不是使用 std::size_t
),我认为有更简单的方法来实现此代码,但这应该可以解决问题。