弱一致性cpu两个线程间传递new的对象的可见性问题

已知
A线程:设置a,再设置pA = &a
B线程:等待pA有效后,再对* pA访问
在x86下可以保证B线程取得a的最新值,但其他更弱一致性的cpu(arm,powerpc)无这种保证,几乎是会出错的。
上面还是比较容易理解的
但是如果延伸一步:
A线程:pA = new {5}
B线程:等待pA有效后,再对*pA访问
在弱一致性cpu上是否能保证正确呢?对pA的赋值是否应当使用atomic的release语义呢……
主要是不明白c++标准是否已经要求弱一致性cpu上new操作有无自带release语义。为了安全似乎是要加了比较放心。没有开发环境希望有人帮测

两线程

#include <iostream>
#include <type_traits>
#include <thread>
#include <assert.h>

struct
{
int value = 0;
                    char _1[128];
int* p = NULL;
                    char _2[128];
volatile bool start = false;
                    char _3[128];
} s_context;

#define TEST_NEW 1

int main()
{
    int* alloced[4] = {};

    std::thread A([&alloced]
    {
        while (!s_context.start)    // 等待start
            ;
#if TEST_NEW == 1
        s_context.p = new int{ 5 }; // 在B申请并归还的地址上,重新申请并赋值5
#else
        s_context.value = 5;
        s_context.p = &s_context.value;
#endif
        printf("A End\n");
    });

    std::thread B([&alloced]
    {
#if TEST_NEW == 1
		//在某个new的位置赋值3,并立刻归还内存,使得此内存位于B的cache之中
        alloced[0] = new int{ 3 };
        delete alloced[0];
#else
        s_context.value = 3;        //在A的工作开始之前,令int value = 3
#endif
        while (!s_context.start)    //等待start
            ;
        while ((int* volatile&)s_context.p == NULL)
            ;
        int* pp = (int* volatile&)s_context.p;
        if (*pp != 5)
        {
            puts("error!");
        }

#if TEST_NEW == 1
        printf("first allocated %p, second allocated %p, %s\n", alloced[0], pp, 
            alloced[0] == pp ? "same address" : "different address");
#endif
        printf("B End\n");
    });

    std::this_thread::sleep_for(std::chrono::milliseconds(300));
    // value应该被B赋值为3了

    s_context.start = true; //令A、B开始
    

    A.join();
    B.join();

//     printf("%p\n", alloced[0]);

    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值