用户定义类型的 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::atomicIncrement
函数。您应该提供增加值的方法,而无需读取,然后写入。
见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)同步的主要内容,如果未能解决你的问题,请参考以下文章
java问题:使用泛型定义学生类,属性score传递不同类型,Integer/Double,实现setter和getter,求大神解答
用户控制:如何在 setter/getter 中的按钮上添加背景图像
Intellij IDEA 自定义 getter and setter