我尝试了解开发线程安全应用程序的正确方法。
在目前的项目中,我有以下课程:
class Test
{
public:
void setVal(unsigned int val)
{
mtx.lock();
testValue = val;
mtx.unlock();
}
unsigned int getVal()
{
unsigned int copy = testValue;
return copy;
}
private:
boost::mutex mtx;
unsigned int testValue;
}
我的问题:多线程环境中的方法Test :: getVal()线程安全,或者在复制之前必须锁定? 我读过一些关于COW的文章,现在我不确定。
谢谢!
答案 0 :(得分:6)
如果您有可以在多个线程(例如您的testValue
成员)之间共享的数据,则必须同步对该数据的所有访问。 "同步"这里有一个广泛的含义:它可以使用互斥锁,通过使数据成为原子,或通过显式调用内存屏障来完成。
但你不能跳过这个。在具有多个线程,CPU内核,CPU和高速缓存的并行世界中,如果他们不握手,那么无法保证一个线程的写入对另一个线程是可见的。"在同步原语上。当线程T2写入testValue
时,线程T1的testValue
缓存条目很可能不会被更新,正是因为硬件缓存管理系统看到"没有发生同步,线程不能访问共享数据,为什么我应该通过使缓存无效来破坏性能?"
C ++ 11标准章节[intro.multithread]比你更喜欢这个,但这里有一个非正式的注释,总结了这个想法:
5 ...非正式地,在 A 上执行释放操作会强制前一方 对其他内存位置的影响,以便以后执行消耗或其他线程的其他线程可见 获取 A上的操作。 ...