分离线程中的竞争条件

时间:2019-03-01 11:13:35

标签: c++ multithreading boost

我试图找到类似的问题,但是找不到,或者我的知识不足以识别相似性。

我有一个创建对象的主循环,而此对象有一个无限循环来处理矩阵并对该矩阵做事。我在单独的线程中将此过程函数称为分离它,因此它能够多次处理矩阵,而主循环可能只是在等待某事而无所事事。

过一会儿,主循环接收到一个新矩阵,而我只是通过创建一个新矩阵并将其传递给对象来表示它。这个想法是,由于在无限while循环中再次处理之前需要等待几秒钟,所以更新功能可以锁定互斥锁,而该互斥锁不会(几乎)被频繁锁定。

下面,我尝试编写一个最小的示例。

class Test
    {
    public:
        Test();
        ~Test();

    void process(){
        while(1){
             boost::mutes::scoped_lock locker(mtx);
             std::cout << "A" << std::endl;
             // do stuff with Matrix
             std::cout << "B" << std::endl;
             mtx.unlock();
             //wait for few microseconds
        }
    }

    void updateMatrix(matrix MatrixNew){
        boost::mutes::scoped_lock locker(mtx);
        std::cout << "1" << std::endl;
        Matrix = MatrixNew;
        std::cout << "2" << std::endl;
    }

private:
    boost::mutex mtx;
    matrix Matrix;
}

int main(){
Test test;
boost::thread thread_;

thread_ = boost::thread(&Test::process,boost::ref(test));
thread_.detach();

while(once_in_a_while){
    Matrix MatrixNew;
    test.updateMatrix(MatrixNew);
}
}

不幸的是,发生了竞赛情况。在锁定的互斥环境中,“处理和更新”有多个步骤,而我在这些步骤之间将内容打印到控制台。我发现,矩阵都被弄乱了,字母/数字平行且不连续。

为什么会出现这种情况?

最良好的祝愿和事先的感谢

1 个答案:

答案 0 :(得分:4)

mtx

您在此处手动解锁scoped_lock。然后过一段时间,locker(称为boost::mutex)也会在其析构函数中解锁互斥对象(这是该类的要点)。我不知道担保书mtx.unlock();的要求,但是将其解锁的​​次数比锁定的次数多就无法带来任何好处。

代替 locker.unlock();您大概想要thread

编辑:此处的建议是避免为此使用boost,而应使用标准c ++。自C ++ 11(8年!)以来,{{1}}成为该标准的一部分,因此大概所有的工具现在都支持它。使用标准化的代码/工具可以为您提供更好的文档和更好的帮助,因为它们已广为人知。我并没有敲响升压(很多标准都是从升压开始的),但是一旦某些东西消耗到了标准中,您就应该认真考虑使用它。