比较 volatile 数组和非 volatile 数组

标签 c arrays multithreading comparison volatile

最近我需要比较两个 uint 数组(一个是 volatile 数组,另一个是非 volatile 数组),结果令人困惑,我一定是对 volatile 数组有一些误解。

我需要从输入设备读取一个数组并将其写入局部变量,然后再将该数组与全局 volatile 数组进行比较。如果有任何不同,我需要将新的复制到全局的,并将新的数组发布到其他平台。代码就像打击一样:

#define ARRAYLENGTH 30
volatile uint8 myArray[ARRAYLENGTH];

void myFunc(void){
    uint8 shadow_array[ARRAYLENGTH],change=0;
    readInput(shadow_array);
    for(int i=0;i<ARRAYLENGTH;i++){
        if(myArray[i] != shadow_array[i]){
            change = 1;
            myArray[i] = shadow_array[i];
            }
        }
    if(change){
        char arrayStr[ARRAYLENGTH*4];
        array2String(arrayStr,myArray);
        publish(arrayStr);
        }
    }

但是,这没有用,每次运行 myFunc 时,都会发布一条新消息,大部分与之前的消息相同。

所以我在代码中插入了一行日志:

for(int i=0;i<ARRAYLENGTH;i++){
    if(myArray[i] != shadow_array[i]){
        change = 1;
        log("old:%d,new:%d\r\n",myArray[i],shadow_array[i]);
        myArray[i] = shadow_array[i];
        }
    }

我得到的日志如下:

old:0,new:0
old:8,new:8
old:87,new:87
...

由于解决 bug 时间紧迫,我解决了以下问题:

char arrayStr[ARRAYLENGTH*4];
char arrayStr1[ARRAYLENGTH*4];
array2String(arrayStr,myArray);
array2String(arrayStr1,shadow_array);
if(strCompare(arrayStr,arrayStr1)){
    publish(arrayStr1);
    }
}

但是,这种方法远非高效。如果有人有合理的解释,我想听听。

谢谢。


[根据评论更新:]

对于 volatile 部分,全局数组必须是 volatile 的,因为其他线程正在访问它。

最佳答案

如果全局数组是易变的,您的跟踪代码可能不准确:

for(int i=0;i<ARRAYLENGTH;i++){
    if(myArray[i] != shadow_array[i]){
        change = 1;
        log("old:%d,new:%d\r\n",myArray[i],shadow_array[i]);
        myArray[i] = shadow_array[i];
        }
    }

问题在于比较行读取了一次myArray[i],但是日志消息再次读取了它,并且由于它是易变的,所以不能保证两次读取会给出相同的值.一种准确的记录技术是:

for (int i = 0; i < ARRAYLENGTH; i++)
{
    uintu_t value;
    if ((value = myArray[i]) != shadow_array[i])
    {
        change = 1;
        log("old:%d,new:%d\r\n", value, shadow_array[i]);
        myArray[i] = shadow_array[i];
    }
}

这会复制比较中使用的值并报告该值。我的直觉是它不会显示出差异,但理论上它可以。

关于比较 volatile 数组和非 volatile 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28660313/

相关文章:

java - 带有返回类型和输入参数的Execute方法

c - 在 STM32F411 Discovery 上实现 HD44780 LCD 时调试 HardFault

c++ - 不以 nul 结尾的常量字符串文字

arrays - 在 Go 中访问二维数组中相邻元素的最有效方法是什么?

PHP array_merge_recursive 与一个数组

java - 如何防止hadoop流关闭?

c# - 您如何跟踪线程/线程上下文?

C中输入的字符计数

c - 如何使用 libpq (PostgreSQL) 将 PGresult 转换为自定义数据类型

arrays - Powershell -notin 数组不会触发 if 语句