本帖最后由 okay007 于 2010-12-26 10:13 编辑
在VC中多线程编程中有一个数据保护问题,如果一个全局变量被多个线程访问,那么它必须被保护,以确保它的值可靠。例如下面一个例子,一个多线程程序在多个线程中对全局整型counter变量的值进行累加。
count = count + 1;
这段代码按照下列CPU指令顺序执行的:
1.将变量值移入处理器的寄存器中
2.增加寄存器中的变量值
3.把寄存器中的变量值写回count变量
由于操作系统可能在线程运行过程中的任意时刻打断线程,所以执行这些指令的两个线程可能按照如下的顺序进行(假设count初始值为5):
线程1:将count变量的值移到寄存器中。(count=5,寄存器=5),然后切换到线程2(count=5,寄存器未知)。
线程2:将count变量的值移到寄存器中(count=5,寄存器=5)。
线程2: 增加寄存器中的值(count=5,寄存器=6)。
线程2: 将寄存器中的值写回count变量(count=6,寄存器=6),然后切换回线程1.(count=6,寄存器=5)。
线程1: 增加寄存器的值。(count=6,寄存器=6)。
线程1: 将寄存器中的值写回count变量(count = 6, register = 6)。
由于线程1在增加变量值并将其写回之前被打断,所以变量count的值被设为6而不是7。
操作系统为系统中地每一个线程的寄存器都保存了副本。即使编写了count++这样的代码,用户还是会遇到相同的问题,因为处理器会将代码按照多条指令执行。
单片机程序中(无操作系统情况)是否也会出现这种问题?
主程序和中断子程序都执行count = count + 1;
主程序:将count变量的值移到寄存器中。(count=5,寄存器=5),
* 此时发生中断,保护断点切换到中断子程序,保护现场,之后中断的(count=5,寄存器未知)。
中断子程序:将count变量的值移到寄存器中(count=5,寄存器=5)。
中断子程序: 增加寄存器中的值(count=5,寄存器=6)。
中断子程序: 将寄存器中的值写回count变量(count=6,寄存器=6),
* 此时中断返回:恢复现场,然后恢复断点返回主程序,主程序的(count=6,寄存器=5)。
主程序: 增加寄存器的值。(count=6,寄存器=6)。
主程序: 将寄存器中的值写回count变量(count = 6, register = 6)。
结果出现和windows编程中多线程同样的问题,count 的值是6而不是7。
如何避免上面的情况发生?也就是最后使count的结果为7,谢谢!
|