C ++ std :: atomic union

Как мне сделать объединение атомарным, используя 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;

};

4

Решение

Это зависит от того, что вы хотите с этим делать. Например, чтобы сохранить значение в атомарном объединении:

foo->value = []{ ValueUnion u; u.floatArray = NULL; return u; }();

или же

foo->value.store([]{ ValueUnion u; u.floatArray = NULL; return u; }());

Если вы хотите иметь возможность выполнять атомарную арифметику без блокировок (например, приращение атома) над содержащимися значениями, то вам нужно будет перейти к второму варианту (объединению атомик).

1

Другие решения

Я полагаю, вам придется использовать атомарный доступ к памяти и пишет:

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 последовательность атомарна. Вам придется самостоятельно разобраться с безопасностью этих инструкций (например, мьютекс)

2

По вопросам рекламы [email protected]