5

如何使用 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

2 回答 2

2

这取决于你想用它做什么。例如,要将值存储到原子联合中:

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

或者

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

如果您希望能够对包含的值执行无锁原子算术(例如原子增量),那么您将需要进行第二个设计(原子联合)。

于 2014-09-16T12:31:16.567 回答
2

我想你必须使用原子内存访问和写入:

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序列是原子的。您必须自己处理这些指令的安全性(例如mutex

于 2014-09-16T12:29:24.873 回答