我通过公共可访问的成员变量命令我的线程,这些变量通常受相应的互斥锁保护。
我的问题是: 如果在写访问期间单个变量受互斥锁保护 它是否也应该在读取访问期间受到保护,或者我可以简单地阅读它吗?
示例:
线程检查是否应该执行特殊操作
( doSpecial 写在另一个帖子中)
// some code
if (doSpecial) {
// code
}
// some code
此读取访问是否应受互斥锁保护?
答案 0 :(得分:2)
是的,如果变量在一个线程上被修改并在其他线程上被访问,则所有访问必须受到互斥锁的保护。没有它,或者其他一些同步方法,不能保证修改是原子的(所以其他线程可能会读取损坏的值),也不能保证其他线程会看到修改后的值(它可能保留在一个处理器的缓存中而且永远不会传播给他人。)
在C ++ 11中,对于简单类型,您可能会考虑std::atomic
而不是由互斥锁保护的非原子变量。
答案 1 :(得分:0)
我不确定,但写一个整数或一个布尔值不是原子的,这很奇怪。我相信写一个双(64位)也可能是原子的。
如果doSpecial是两个线程直接访问的布尔变量,则需要使用“volatile”限定它。这将阻止编译器为其使用缓存。
如果不这样做,执行测试的函数( if(doSpecial))可以将变量映射到处理器内部缓存中,而 if -test可以永远不会看到价值变化。
使用互斥锁不会阻止编译器对变量进行此类优化。
最好的方法是通过函数访问该值:
if ( isSpecial() ) ...
setSpecial( bool ){ ... }
如果它们在多个布尔值上工作,它允许您在两个函数中添加互斥锁管理