如何防止main()在单独的线程访问时改变变量

时间:2013-01-29 05:10:29

标签: c++ multithreading c++11 mutex

我的程序基于“世界”类(基本上是“世界”包含子类“tile”的2D矢量,它可以容纳各种变量,这些变量可以在不同的块之间移动,也可以被删除)在main()中。 main()处理“world”本身的更新,而函数updateDisplay()在监视器上显示“world”的内容。 updateDisplay()由一个单独的C ++ 11线程(在main()中启动)运行,并通过传递的引用访问“world”。

我的问题是我遇到了罕见的崩溃,因为在下面的updateDisplay()的(简化)代码摘录中,矢量world.m_grid [i] [j] .m_rabbit偶尔被main()清除在“if(!world.m_grid [i] [j] .m_rabbit.empty())”之后检入updateDisplay(),但在随后访问m_rabbit [0]向量成员之前,导致“向量下标”范围“错误。

for (int i = 0; i < rows; ++i)
{
    for (int j = 0; j < columns; ++j)
    {

        if (!world.m_grid[i][j].m_rabbit.empty())
        {
            s_rabbit_64.setScale(absTileScale * world.m_grid[i][j].m_rabbit[0].m_size, absTileScale * world.m_grid[i][j].m_rabbit[0].m_size);
            s_rabbit_64.setPosition(x * k + (12 * absTileScale), y * (i - winFocus.y) + (12 * absTileScale));
            window.draw(s_rabbit_64);
        }
    }
}

我的问题是,如何锁定world.m_grid [i] [j] .m_rabbit向量,以便main()在updateDisplay()线程访问它时不能改变它?我认为这是通过使用std :: mutex来实现的,但我一直无法找到一个能够让我对此有充分理解的指南,以便将它应用到我的程序中。我希望这一点足够清楚(程序比这个摘录大得多,我不想做大量的文本转储),请询问你需要的任何要点。

谢谢你的关注。

[编辑]拼写

2 个答案:

答案 0 :(得分:3)

欢迎来到多线程的狂野和毛茸茸的世界。坐;你会来这里很长时间。就像在,你的其余编程生涯有点长。它是可怕的,充满了背叛和微妙的错误,并且如果你能做到这一点,也会付出非常: - )

实际上,你已经很好地识别了这种情况下的具体错误。你需要的是拥有一个互斥锁来保护所有访问和线程之间共享的状态突变。在您的情况下:在清除向量之前锁定主线程中的互斥锁,并在完成后解锁互斥锁。同样,在访问它之前锁定处理线程中的互斥锁,并在完成后将其解锁。在这种特殊情况下,你可能最终会锁定你去那里的整个双for循环。

This answer是对互斥体正在做什么的很好的解释。


是的,有更快更优雅的做事方式,但现在让我们坚持正确。

答案 1 :(得分:1)

您需要识别代码的关键部分。从您上面发布的内容来看,似乎任何修改world.m_grid [i] [j] .m_rabbit的操作都是一个关键部分。

然后您需要某种同步技术,这样任何时候只有1个线程可以进入特定的临界区(例如互斥)。

你需要在网上搜索一些好的阅读 - 或者甚至更好地找到一本好的编程书并花些时间在并发章节上。