• InterLockedIncrement and InterLockedDecrement函数原理


    实现数的原子性加减。

    什么是原子性的加减呢?

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

  • 相关阅读:
    Linux线程信号
    有理想的程序员必须知道的15件事
    Linux下 mplayer 使用手册
    Winxp下 gvim 编程环境搭建
    在WPF中弹出右键菜单时判断鼠标是否选中该项
    F#基本类型——Discriminated Unions
    在WPF的TreeView中实现右键选定
    WPF TreeView tools
    F#基本类型——Structure
    增强了一下DownloaderPlus的视频转换功能
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5222387.html
Copyright © 2020-2023  润新知