我有一个与uint64_t结合的结构,提供对两个int32_t的访问。我想原子地减少其中一个struct成员。我想出了这个:
class{
public:
void atomicallyDecrement_B(const int32_t decrementByThisValue){
MyUnion newUnion;
MyStruct currentStruct = _union._data;
do{
const int32_t currentB = currentStruct.b;
const int32_t currentA = currentStruct.a;
const int32_t newB = currentB - decrementByThisValue;
newUnion._data.a = currentA;
newUnion._data.b = newB;
}
while(!std::atomic_compare_exchange_weak(&_union._data, ¤tStruct, newUnion._data));
}
private:
struct MyStruct{
int a;
int b;
};
union MyUnion{
MyUnion(){
_data.a = 0;
_data.b = 0;
}
MyStruct _data;
uint64_t _atomic;
} _union;
};
但
atomic_compare_exchange_weak()
的第一个参数似乎必须是原子类型本身。有什么方法可以执行此操作而无需将uint64_t数据成员更改为std::atomic<uint64_t>
?我正在使用GCC 5.2
最佳答案
GCC具有内置的原子操作。它们在this page上描述。
您正在寻找的操作是
type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...)
要么
bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
这些内建函数执行原子比较和交换。也就是说,如果* ptr的当前值为oldval,则将newval写入* ptr。
对于Windows用户,相应的功能是
LONG __cdecl InterlockedCompareExchange(
_Inout_ LONG volatile *Destination,
_In_ LONG Exchange,
_In_ LONG Comparand
);
在here中描述
使用gcc内在函数的布尔形式的示例:
do{
int oldVal = protectedVal;
int newVal = someFunction(oldVal);
} while (__sync_bool_compare_and_swap(&protectedVal, oldVal, newVal);
关于c++ - 以原子方式减少 union 的数据成员?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33531686/