实现数的原子性加减。
什么是原子性的加减呢?
举个样例:假设一个变量 Long value =0;
首先说一下正常情况下的加减操作:value+=1。
1:系统从Value的空间取出值,并动态生成一个空间来存储取出来的值;
2:将取出来的值和1作加法。而且将和放回Value的空间覆盖掉原值。
加法结束。
假设此时有两个Thread 。分别记作threadA。threadB。
1:threadA将Value从存储空间取出。为0。
2:threadB将Value从存储空间取出,为0。
3:threadA将取出来的值和1作加法。而且将和放回Value的空间覆盖掉原值。
加法结束。Value=1。
4:threadB将取出来的值和1作加法。而且将和放回Value的空间覆盖掉原值。
加法结束,Value=1。
最后Value =1 ,而正确应该是2;这就是问题的所在。InterLockedIncrement 可以保证在一个线程訪问变量时其他线程不能訪问。同理InterLockedDecrement。
volatile:将一个变量说明为volatile表示这个变量是“易变的”。假设一个变量会被其他引用改变。或在其他并行的任务中会被改变(比如中断服务程序),都要显式地说明为“volatile”,否则在编译器优化阶段会作出错误的推断,比如将这个变量读入寄存器以后。在没有对这个变量赋值曾经,会一直使用寄存器中的值。而实际上这个变量的值可能已经被一个指针引用改变了。或者是在中断服务程序中被改变了,以下这个样例说明这样的错误:
有一个变量T,在定时中断中每隔一个固定时间减一。然后在主程序中等待它减到0
unsigned char T;
void T0_int( void ) interrupt 1
{
...
T--;
...
}
int main( int )
{
...
T = 10;
while ( T != 0 ); /* 这在某些编译器中将成为一个死循环,而不是预想的等待一段时间 */
...
}
正确的写法应该是将第一句改为:
volatile unsigned char T;