Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将易失性阵列与非易失性阵列进行比较_C_Arrays_Multithreading_Comparison_Volatile - Fatal编程技术网

C 将易失性阵列与非易失性阵列进行比较

C 将易失性阵列与非易失性阵列进行比较,c,arrays,multithreading,comparison,volatile,C,Arrays,Multithreading,Comparison,Volatile,最近我需要比较两个uint阵列(一个是易失性阵列,另一个是非易失性阵列),结果令人困惑,我对易失性阵列有一些误解 我需要从输入设备读取数组并将其写入局部变量,然后再将该数组与全局volatile数组进行比较。如果有任何差异,我需要将新阵列复制到全局阵列,并将新阵列发布到其他平台。代码是一种打击: #define ARRAYLENGTH 30 volatile uint8 myArray[ARRAYLENGTH]; void myFunc(void){ uint8 shadow_arra

最近我需要比较两个uint阵列(一个是易失性阵列,另一个是非易失性阵列),结果令人困惑,我对易失性阵列有一些误解

我需要从输入设备读取数组并将其写入局部变量,然后再将该数组与全局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);
        }
    }
由于解决bug是时间关键性的,我解决了以下问题:

old:0,new:0
old:8,new:8
old:87,new:87
...
char arrayStr[ARRAYLENGTH*4];
char arrayStr1[ARRAYLENGTH*4];
array2String(arrayStr,myArray);
array2String(arrayStr1,shadow_array);
if(strCompare(arrayStr,arrayStr1)){
    publish(arrayStr1);
    }
}
但是,这种方法远远不够有效。如果有人有合理的解释,我想听听

多谢各位


[根据评论更新:]


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

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

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];
        }
    }

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

如果全局数组不稳定,则跟踪代码可能不准确:

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];
        }
    }
这将复制比较中使用的值并报告该值。我的直觉是,这不会显示出什么不同,但理论上是可以的

全局数组必须是可变的,因为其他线程正在访问它

正如您“很好地”观察到的,声明数组
volatile
并不是防止不同线程并发读/写访问的方法

为此使用互斥锁。例如,通过将对“全局数组”的访问包装到一个函数中,该函数将锁定和解锁此互斥锁。然后仅使用此功能访问“全局数组”

参考资料:


对于
printf()
ing
unsigned
整数,也使用转换说明符
u
not
d

全局数组必须是可变的,因为其他线程正在访问它

正如您“很好地”观察到的,声明数组
volatile
并不是防止不同线程并发读/写访问的方法

为此使用互斥锁。例如,通过将对“全局数组”的访问包装到一个函数中,该函数将锁定和解锁此互斥锁。然后仅使用此功能访问“全局数组”

参考资料:


同样,对于
printf()
ing
无符号
整数,使用转换说明符
u
not
d
当变量(或数组)可能在当前程序执行流之外更改时,应将其声明为易失变量。这可能通过并发线程或ISR实现。 但是,如果只有一个真正向其写入,而其他所有人都是jsut读取器,那么实际编写的代码可能会将其视为不易失性(即使无法告诉编译器这样做)

因此,如果比较函数是项目中唯一一个实际更改(更新)gloal数组的点,那么多次读取就没有问题。代码可以在(外部)知识的基础上进行设计,即尽管有volatile声明,外部源不会进行任何更改

然而,“读取器”确实知道变量(或数组内容)可能会更改,并且不会缓冲它读取的数据(例如,通过将读取数据存储在寄存器中以供进一步使用),但在读取时数组内容可能会更改,并且整个信息可能不一致。 所以建议使用互斥是个好主意。 然而,这无助于解决比较循环失败的原始问题,即使没有人从外部干扰数组

此外,我想知道,如果myArray仅在本地使用,并且发布是通过发送指向ArrayStr的指针(这是指向非易失性字符(数组)的指针)完成的,那么为什么myArray会被声明为volatile。 没有理由认为myArray应该是易变的。实际上,根本没有理由认为它存在: 只需读入数据,创建一个临时字符串,如果它与原始字符串不同,则替换旧字符串并发布它。好吧,总是构建字符串可能效率较低,但它会使代码更短,而且显然有效

static char arrayStr[ARRAYLENGTH*4]={};
char tempStr[ARRAYLENGTH*4];
array2String(tempStr,shadow_array);
if(strCompare(arrayStr,tempStr)){
    strCopy(arrayStr, tempStr);
    publish(arrayStr);
    }
}
当变量(或数组)可能在当前程序执行流之外更改时,应将其声明为volatile。这可能由并发线程或ISR发生。 但是,如果只有一个真正向其写入,而其他所有人都是jsut读取器,那么实际编写的代码可能会将其视为不易失性(即使无法告诉编译器这样做)

因此,如果比较函数是项目中唯一一个实际更改(更新)gloal数组的点,那么多次读取就没有问题。代码可以在(外部)知道外部源不会更改的情况下进行设计,尽管有volatile声明

然而,“读取器”确实知道变量(或数组内容)可能会更改,并且不会缓冲它读取的数据(例如,通过将读取数据存储在寄存器中以供进一步使用),但在读取时数组内容可能会更改,并且整个信息可能不一致。 所以建议使用互斥是个好主意。 然而,这无助于解决比较循环失败的原始问题,即使没有人从外部干扰数组

此外,我想知道,如果myArray仅在本地使用,并且发布是通过发送指向ArrayStr的指针(这是指向非易失性字符(数组)的指针)完成的,那么为什么myArray会被声明为volatile。 没有理由认为myArray应该是易变的。实际上,根本没有理由认为它存在: 只需读入数据,创建一个临时字符串,如果它与原始字符串不同,则替换旧字符串并发布它。好吧,总是构建字符串可能效率较低,但它会使代码更短、更简单
static char arrayStr[ARRAYLENGTH*4]={};
char tempStr[ARRAYLENGTH*4];
array2String(tempStr,shadow_array);
if(strCompare(arrayStr,tempStr)){
    strCopy(arrayStr, tempStr);
    publish(arrayStr);
    }
}