我试图了解开发线程安全应用程序的正确方法。
在当前项目中,我有以下类(class):
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 的文章,现在我不确定。
谢谢!
最佳答案
如果您有可以在多个线程之间共享的数据(例如您的情况下的 testValue
成员),则必须同步对该数据的所有访问。 “同步”在这里具有广泛的含义:可以使用互斥锁、通过使数据原子化或显式调用内存屏障来完成。
但是你不能跳过这一点。在具有多个线程、CPU 内核、CPU 和缓存的并行世界中,如果一个线程不与同步原语“握手”,则不能保证一个线程的写入对另一个线程可见。当线程 T2 写入 testValue
时,线程 T1 的 testValue
缓存条目很有可能不会更新,正是因为硬件缓存管理系统看到“没有同步发生,线程不访问共享数据,我为什么要破坏性能通过使缓存无效?”
C++11 标准章节 [intro.multithread] 比你想要的更详细,但这里有一个来自该章节的非正式注释总结了这个想法:
关于c++ - 写时复制的线程安全,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24632864/