3

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

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

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() 在多线程环境中是线程安全的,还是必须在复制之前锁定?我读过一些关于牛的文章,现在我不确定。

谢谢!

4

1 回答 1

6

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

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

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

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

于 2014-07-08T13:22:56.427 回答