用户定义类型的 getter 和 setter 上的 C++(类似 CAS)同步

Posted

技术标签:

【中文标题】用户定义类型的 getter 和 setter 上的 C++(类似 CAS)同步【英文标题】:C++ (CAS-like) synchronization on getter and setter of user defined types 【发布时间】:2013-10-08 04:29:10 【问题描述】:

假设有一个用户定义的类MyClass,它有一个setter 和一个getter 函数。

class MyClass 
    int m_value;
    public:
        void set(int value)
         m_value = value; 

        int get() const
         return m_value;
;

还有一个函数increment()可以将对象的值加1,可以在多个线程中调用。

void increment(MyClass& myClass)

    myClass.set(myClass.get() + 1);

使这个函数线程安全的最好方法是什么?只使用锁?有什么办法可以通过一些类似 CAS 的操作来实现吗?

【问题讨论】:

你不太可能需要原子,它们甚至可能更慢,最好用互斥锁来保护类的数据。 你当然可以添加 myClass::increment() 方法。 【参考方案1】:

如果您使用的是 C++11,您可以只使用std::atomic<int>,它提供原子load、store 和increment,这似乎是您需要的一切。

我怀疑您不需要原子,尽管在大多数情况下它们会比您的基本互斥锁慢。

在您做出决定之前,请查看其他 question。

【讨论】:

我不认为std::atomic<int> 会起作用,因为我使用的是用户定义的类型。感谢您的建议和链接。 所以你唯一的解决方案就是用互斥锁来保护它。简化决策;) 我的意思是在你的 MyClass 内部使用 std::atomic。如果这就是您所说的用户定义类型。 @user571470 如果值是原子的,他们就不能这样做。递增操作是有序的。不安全的是您的 Increment 函数。您应该提供增加值的方法,而无需读取,然后写入。 见coliru.stacked-crooked.com/a/e0aa11350d653bb2 这两者都没有数据竞争,但根据您使用它们的方式,它们可能在逻辑上不正确。这就是使类线程安全的困难。【参考方案2】:

使用 std::mutex 并享受

    #include <mutex>

    class MyClass 
    
        int m_value;
        std::mutex mtx;

        void set(int value) 
        
            mtx.lock();
            m_value = value;
            mtx.unlock();
        

        int get() const 
        
            return m_value;
        
     

【讨论】:

这行不通。 increment() 仍然不是线程安全的。 increment() 不需要线程安全,因为 MyClass.set 函数是线程安全的。 但是两个线程可以用相同的值调用set(),这不是两次递增值的想法。

以上是关于用户定义类型的 getter 和 setter 上的 C++(类似 CAS)同步的主要内容,如果未能解决你的问题,请参考以下文章

getter和setter方法

java问题:使用泛型定义学生类,属性score传递不同类型,Integer/Double,实现setter和getter,求大神解答

用户控制:如何在 setter/getter 中的按钮上添加背景图像

Intellij IDEA 自定义 getter and setter

使用 Symfony 2 CLI 工具,如何为子类生成具有正确类型提示的 getter 和 setter?

Object C 属性、特性、类型