[C语言]多线程几乎同时读写同一个内存地址时,出现变量概率不刷新问题

【现象】:linux,c语言程序, -O3优化。线程a对变量x赋值,int x=0,并将变量x地址传给线程b,线程b对变量x再次执行赋值操作x=2,此时在线程a内部访问变量x,值仍然为0,并未立刻刷新。

【解决过程】:
① 尝试对x变量类型前加volatile关键字:问题仍然存在,原因是虽然volatile会要求每次读取变量都从主存读取,但由于cpu cache的存在,仍然读取的是cache中的内容,此方法无法彻底解决多线程访问变量及时刷新的问题;
② 将x由普通的int类型变为指针类型int *x,每次从指针读取一个malloc的int类型变量,问题解决。原因可能是指针的读取操作会进行二次寻址,不会受到cpu cache的影响。

linux c,简单测试代码:
编译命令:

gcc -g -O3 -o main main.c -pthread
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <memory.h>
#include <stdlib.h>

typedef struct test {
    int *a; // 即便先启动thread2(避免线程启动时间影响),后启动thread1,用volatile 还是有可能thread1变量没有刷新(一定的概率)
} test_t;

void *thread1(void *param)
{
    test_t *p_param = param;
    //p_param->a = -2;
    usleep(1000);
    test_t *p_param2 = (test_t *)(param + sizeof(test_t));
    while (1) {
        printf("%p\n", p_param2->a);
        if (NULL != p_param2->a) {
            printf("%d\n", *(p_param2->a));
            break;
        }
    }

    return NULL;
}

void *thread2(void *param)
{
    usleep(900);
    test_t *p_param = param;
    test_t *p_param2 = (test_t *)(param + sizeof(test_t));
    int *p = (int *)malloc(sizeof(int));
    *p = 3;
    p_param2->a = p;
    printf("after %d\n", *(p_param2->a));
    return NULL;
}

int main()
{
    pthread_t t[2];
    int r[2];
    test_t *a = (test_t *)malloc(2 * sizeof(test_t));
    memset(a, 0x00, 2 * sizeof(test_t));

    r[1] = pthread_create(&t[1], NULL, thread2, (void *)a);
    r[0] = pthread_create(&t[0], NULL, thread1, (void *)a);

    pthread_join(t[0], NULL);
    pthread_join(t[1], NULL);

    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值