下面代码输出的是什么
示例一
struct B {
atomic_int y;
B() : y(0) {}
};
struct A {
B *b;
int x;
A():x(0){}
};
int main() {
A a;
a.b = new B;
atomic<A> x;
x.exchange(a);
auto a1 = x.load();
auto a2 = x.load();
a1.b->y.fetch_add(1);
if (x.compare_exchange_strong(a1, a2)) {
cout << "eq" << endl;
}
}
答案是什么也不输出, 这个有一点出乎意料了
下面输出什么
示例二
struct B {
atomic_int y;
B() : y(0) {}
};
struct A {
B *b;
// int x;
A(){}
};
int main() {
A a;
a.b = new B;
atomic<A> x;
x.exchange(a);
auto a1 = x.load();
auto a2 = x.load();
a1.b->y.fetch_add(1);
if (x.compare_exchange_strong(a1, a2)) {
cout << "eq" << endl;
}
}
答案是输出eq
这二者有什么差异呢, 我们仅仅将 int x 注释掉了
揭露真相之旅
compare_exchange_strong|weak 在比较相等时用的是
memcpy 逐位比较
但是a1 和 x 逐位比较也应该想等才对呀,那问题出现在哪里呢
答案是:内存对齐导致的额外的padding
示例一 内存不对齐的大小是 8 + 4 = 12B
但是因为内存对齐导致其大小为 16B
memcpy 比较了16, 有4个字节的内容是未知的
解决问题方法
1、将上面的int x 改成 long long x, 这样就不会有4字节的填充