写入时副本的线程安全性

时间:2014-07-08 13:15:33

标签: c++ multithreading copy-on-write

我尝试了解开发线程安全应用程序的正确方法。

在目前的项目中,我有以下课程:

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的文章,现在我不确定。

谢谢!

1 个答案:

答案 0 :(得分:6)

如果您有可以在多个线程(例如您的testValue成员)之间共享的数据,则必须同步对该数据的所有访问。 "同步"这里有一个广泛的含义:它可以使用互斥锁,通过使数据成为原子,或通过显式调用内存屏障来完成。

但你不能跳过这个。在具有多个线程,CPU内核,CPU和高速缓存的并行世界中,如果他们不握手,那么无法保证一个线程的写入对另一个线程是可见的。"在同步原语上。当线程T2写入testValue时,线程T1的testValue缓存条目很可能不会被更新,正是因为硬件缓存管理系统看到"没有发生同步,线程不能访问共享数据,为什么我应该通过使缓存无效来破坏性能?"

C ++ 11标准章节[intro.multithread]比你更喜欢这个,但这里有一个非正式的注释,总结了这个想法:

  

5 ...非正式地,在 A 上执行释放操作会强制前一方   对其他内存位置的影响,以便以后执行消耗或其他线程的其他线程可见   获取 A上的操作。 ...