双线程 C++ 程序在打印向量的奇数和偶数元素方面没有进展

问题描述 投票:0回答:1

我被要求在面试期间实现一个程序,该程序生成 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 语句进行调试,但程序没有显示标准输出,并且执行代码只是无限期地挂起。 请建议我如何进一步调试或者当前程序有什么问题。

c++ multithreading c++20 condition-variable
1个回答
0
投票

您没有看到任何输出,因为输出是行缓冲的,并且您从不写

'\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
),我认为有更简单的方法来实现此代码,但这应该可以解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.