Как мне сделать объединение атомарным, используя std :: atomic? Или я должен объявить членов союза атомарными?
typedef union {
int integer;
float flt;
double dbl;
int *intArray;
float *floatArray;
unsigned char *byteArray;
} ValueUnion;
class FooClass {
public:
std::atomic<ValueUnion> value;
};
Доступ к объединению дает ошибку:
foo->value.floatArray = NULL;
error: no member named 'floatArray' in 'std::__1::atomic<ValueUnion>'
foo->value.floatArray = NULL;
Нужно ли делать что-то вроде:
typedef union {
std::atomic<int> integer;
std::atomic<float> flt;
std::atomic<double> dbl;
std::atomic<int*> *intArray;
std::atomic<float*> *floatArray;
std::atomic<unsigned char*> *byteArray;
} ValueUnion;
и объявить значение переменной члена, как показано ниже?
class FooClass {
public:
ValueUnion value;
};
Это зависит от того, что вы хотите с этим делать. Например, чтобы сохранить значение в атомарном объединении:
foo->value = []{ ValueUnion u; u.floatArray = NULL; return u; }();
или же
foo->value.store([]{ ValueUnion u; u.floatArray = NULL; return u; }());
Если вы хотите иметь возможность выполнять атомарную арифметику без блокировок (например, приращение атома) над содержащимися значениями, то вам нужно будет перейти к второму варианту (объединению атомик).
Я полагаю, вам придется использовать атомарный доступ к памяти и пишет:
typedef union {
int integer;
float flt;
double dbl;
int *intArray;
float *floatArray;
unsigned char *byteArray;
} ValueUnion;
class FooClass {
public:
std::atomic<ValueUnion> value;
};
int main()
{
FooClass obj;
ValueUnion temp = obj.value.load();
temp.floatArray = NULL;
obj.value.store(temp);
}
обратите внимание, что это не гарантирует, что load/modify/store
последовательность атомарна. Вам придется самостоятельно разобраться с безопасностью этих инструкций (например, мьютекс)