我是否应该在一个线程中锁定一个变量,如果我只需要它在其他线程中的值,为什么它不工作?

Bre*_*ugh 5 c c++ opengl multithreading sdl

我知道这个问题,但我相信我的担忧是非常不同的.

我最近使用线程和OpenGL创建了一个SDL应用程序.我有一个线程在循环中运行,它不断更新我绘制到屏幕的对象的状态.状态非常简单,它只是一个布尔数组(当数组值为true时,我绘制它,当它为假时,我没有).

目前,我的任何变量都没有互斥锁,一切正常.即使只有一半的状态数组在绘制之间更新,帧速率也要高得多(或至少等于)更新速率,因此具有半更新状态是可以接受的.

现在,我最初在使用中断的嵌入式系统上开始研究类似的想法.每隔一段时间,一个中断就会触发,更新状态数组,执行将继续.现在,我是一个多核桌面上,并同时更新数组,我不知道为什么没有什么不好的正在发生的事情,因为我在技术上读取和写入同一个存储单元在同一时间.

  • 这只是偶然的,还是有理由没有发生内存访问违规?
  • 如果在使用该值之前,期间或之后变量的状态是可以接受的,那么我是否应该使用互斥锁?

谢谢您的帮助.


编辑:附加信息 - 数组是动态创建的,但是当它被创建/删除时,我确实使用了一个互斥锁(我认为访问已删除的内存不会看起来很友好:P).

R..*_*R.. 8

理论上,在没有某些同步的情况下访问这样的内存是完全无效的(未定义的行为).

在实践中,只要符合以下条件,它就是中等安全的:

  1. 只有一个线程在写,其他线程都在读.
  2. 如果读者在一段时间之后没有看到一些变化(可能比他们写入的实际时间得多),你不在乎.
  3. 您不关心读者是否看到无序更改,即他们会看到稍后进行的某些更改,而不会看到之前进行的其他更改.

问题2和3在x86上不是问题,但几乎可以在所有其他真实世界的多核/ SMP机器上发生.您可以使用某些特定于机器的asm(或编译器内在函数)来缓解它们,以在适当的位置插入内存屏障.

  • 不要忘记原子性 - 如果读取/写入的数量不是机器字大小(更小和更大),或者如果读取/写入未对齐的值,则可以看到对象的不一致状态. (3认同)
  • 无论如何,对于你的特定例子,它根本不重要.最糟糕的事情是你的应用程序在一帧或另一帧中绘制了太多的对象......所以. (2认同)