c++ compare_exchange_strong|weak使用小陷阱

下面代码输出的是什么

示例一

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字节的填充

你可能感兴趣的:(c++)