c++ - 写时复制的线程安全

标签 c++ multithreading copy-on-write

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

在当前项目中,我有以下类(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 缓存条目很可能不会更新,正是因为 HW 缓存管理系统看到“没有同步发生,线程不访问共享数据,我为什么要通过使缓存无效来破坏性能?”

C++11 标准章节 [intro.multithread] 对此进行了比您想要的更详细的介绍,但这是该章的非正式注释,总结了这个想法:

5 ... Informally, performing a release operation on A forces prior side effects on other memory locations to become visible to other threads that later perform a consume or an acquire operation on A. ...

关于c++ - 写时复制的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24632864/

相关文章:

string - 当字符串没有自动触发时如何触发 COW

c++ - 如何在不格式化的情况下写入 std::ostream?

c++ - 为什么 "cc1plus: warning: unrecognized command line option"选项的 "no-"仅在出现另一个警告时由 g++ 标记?

multithreading - 如何避免消息队列泛滥?

java - java 多线程间共享对象

stack - 堆栈的写时复制

linux - 哪些段受写时复制影响?

c++ - glBlendFunc 和 alpha channel

c++ - 为什么我的线程被一个没有被任何东西占用的关键部分阻塞?

c# - 如何同步事件处理程序