实现数的原子性加减。

什么是原子性的加减呢?

举个样例:假设一个变量 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;

InterLockedIncrement and InterLockedDecrement函数原理的更多相关文章

  1. win32的计数增减操作的原子操作--InterLockedIncrement和InterlockedDecrement

    InterLockedIncrement and InterLockedDecrement 实现数的原子性加减. 什么是原子性的加减呢? 举个例子:如果一个变量 Long value =0; 首先说一 ...

  2. 不定参数函数原理以及实现一个属于自己的printf函数

    一.不定参数函数原理 二.实现一个属于自己的printf函数 参考博文:王爽汇编语言综合研究-函数如何接收不定数量的参数

  3. map函数原理

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #map函数 #map函数会对一个序列对象中的每一个元素应用被传入的函数,并返回一个包含了所有函数调用结果的一 ...

  4. C# Async/Await异步函数原理

    原理 与同步函数相比,CLR在执行异步函数时有几个不同的特点: 1.        并非一次完成,而且分多次完成 2.        并非由同一个线程完成,而是线程池每次动态分配一个线程来处理: 结合 ...

  5. Block、委托、回调函数原理剖析(在Object C语境)——这样讲还不懂,根本不可能!

    开篇:要想理解Block和委托,最快的方法是搞明白“回调函数”这个概念. 做为初级选手,我们把Block.委托.回调函数,视为同一原理的三种不同名称.也就是说,现在,我们把这三个名词当成一回事.在这篇 ...

  6. 树状数组lowbit()函数原理的解释 x&(x^(x-1)) x&-x

    树状数组lowbit()函数所求的就是最低位1的位置所以可以通过位运算来计算 树状数组通过 x&(x^(x-1)) 能够成功求出lowbit的原因: 首先设x=6,即110(2) 于是我们使 ...

  7. C函数原理

    C语言作为面向过程的语言,函数是其中最重要的部分,同时函数也是C种的一个难点,这篇文章希望通过汇编的方式说明函数的实现原理. 栈结构与相关的寄存器 在计算中,栈是十分重要的一种数据结构,同时也是CPU ...

  8. C++虚函数原理

    类中的成员函数分为静态成员函数和非静态成员函数,而非静态成员函数又分为普通函数和虚函数. Q: 为什么使用虚函数 A: 使用虚函数,我们可以获得良好的可扩展性.在一个设计比较好的面向对象程序中,大多数 ...

  9. php回调函数原理和实例

    原理 自己调用自己 称之为“递归”,而不是回调 你也知道回调的关键是这个回既然是回,那么就有一个谁是主体的问题,因为回调是往回调用的意思我调用了函数A,而函数A在执行过程中调用了我提供的函数B,这个函 ...

随机推荐

  1. 代码中实际运用memcached——mycode

    1.下载安装64位memcached.exe  下载地址:http://blog.couchbase.com/memcached-windows-64-bit-pre-release-availabl ...

  2. Android 属性动画(Property Animation) 全然解析 (下)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38092093 上一篇Android 属性动画(Property Animatio ...

  3. Android应用程序窗口(Activity)的测量(Measure)、布局(Layout)和绘制(Draw)过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8372924 在前面一篇文章中,我们分析了And ...

  4. linux下挂载iso镜像文件(转)

    挂接命令(mount) 首先,介绍一下挂接(mount)命令的使用方法,mount命令参数非常多,这里主要讲一下今天我们要用到的. 命令格式: mount [-t vfstype] [-o optio ...

  5. uploadify按钮中文乱码问题

    uploadify是一款基于jQuery库的上传插件,但很可惜的是无论你怎么设置参数buttonText ,它的中文按钮都会出现乱码的情况,现把出现原因及解决方法总结如下.       那么出现这种的 ...

  6. LINQ 操作符(二)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  7. DEVC++生成DLL的方法

    通过网上一个MD5加密算法源码生成DLL 一.建立DLL项目并编译 DEVC++创建C项目,选择DLL, 一共4个文件及源码如下: dll.h dllmain.c md5.c md5.h 函数参数: ...

  8. linux配置加载顺序

    linux加载配置项时通过下面方式 首先 加载/etc/profile配置 然后 加载/ect/profile.d/下面的所有脚本 然后 加载当前用户 .bash_profile 然后 加载.bash ...

  9. PDO扩展使用方法

    pdo扩展为php访问数据库提供了一个轻量级的一致接口,pdo提供了一个数据访问抽象层,这意味着不管使用哪种数据库,都可以使用相同的函数来查询和获取数据. $dbms='mysql'; //数据库类型 ...

  10. BestCoder 2nd Anniversary 1001 Oracle

    找到最小的非零数字拆开来相加. 高精度. #include <iostream> #include <cstdio> #include <cstring> #inc ...