具有非原子变量的C ++ 11原子存储顺序 [英] C++11 Atomic memory order with non-atomic variables
问题描述
我不确定c ++ 11中原子变量的内存排序保证如何影响对其他内存的操作.
I am unsure about how the memory ordering guarantees of atomic variables in c++11 affect operations to other memory.
假设我有一个线程定期调用write函数以更新值,而另一个线程调用read以获取当前值.
Let's say I have one thread which periodically calls the write function to update a value, and another thread which calls read to get the current value. Is it guaranteed that the effects of d = value;
will not be seen before effects of a = version;
, and will be seen before the effects of b = version;
?
atomic<int> a {0};
atomic<int> b {0};
double d;
void write(int version, double value) {
a = version;
d = value;
b = version;
}
double read() {
int x,y;
double ret;
do {
x = b;
ret = d;
y = a;
} while (x != y);
return ret;
}
推荐答案
是否保证
d = value;
的效果不会在a = version;
的效果之前看到,并且会在b = version;
的效果之前看到?
Is it guaranteed that the effects of
d = value;
will not be seen before effects ofa = version;
, and will be seen before the effects ofb = version;
?
是的.这是因为在读取或写入atomic<>
变量时暗含了顺序一致性障碍.
Yes, it is. This is because sequensial consistency barrier is implied when read or write atomic<>
variable.
在修改值之前和之后,不必将version
标记存储到两个原子变量中,而是可以在修改之前和之后将单个原子变量递增:
Instead of storing version
tag into two atomic variables before value's modification and after it, you can increment single atomic variable before and after modification:
atomic<int> a = {0};
double d;
void write(double value)
{
a = a + 1; // 'a' become odd
d = value; //or other modification of protected value(s)
a = a + 1; // 'a' become even, but not equal to the one before modification
}
double read(void)
{
int x;
double ret;
do
{
x = a;
ret = value; // or other action with protected value(s)
} while((x & 2) || (x != a));
return ret;
}
在Linux内核中称为 seqlock : http://en .wikipedia.org/wiki/Seqlock
This is known as seqlock in the Linux kernel: http://en.wikipedia.org/wiki/Seqlock
这篇关于具有非原子变量的C ++ 11原子存储顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!