写入时副本的线程安全性

use*_*620 3 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;
}
Run Code Online (Sandbox Code Playgroud)

而我的问题是:在多线程环境中上面的方法是Test :: getVal()threadsafe,还是在复制前必须锁定?我读过一些关于COW的文章,现在我不确定.

谢谢!

Rei*_*ica 6

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

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

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

5 ...非正式地,对A执行释放操作会强制对其他内存位置产生先前的副作用,以便其他线程可见,以便稍后对A执行消耗或获取操作.