• InterLockedIncrement and InterLockedDecrement函数原理


    http://hi.baidu.com/drunkdream/blog/item/014e1cce56efe730b600c88e.html

    InterLockedIncrement and InterLockedDecrement函数原理

    2009-07-01 20:57InterLockedIncrement 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。

    LONG   InterlockedDecrement(  
          LPLONG   lpAddend       //   variable   address  
    );  
    属于互锁函数,用在同一进程内,需要对共享的一个变量,做减法的时候,  
    防止其他线程访问这个变量,是实现线程同步的一种办法(互锁函数)
      
    首先要理解多线程同步,共享资源(同时访问全局变量的问题),否则就难以理解。  
        
    result   =   InterlockedDecrement(&SomeInt)  
        
    如果不考虑多线程其实就是   result   =   SomeInt   -   1;  
        
    但是考虑到多线程问题就复杂了一些。就是说如果想要得到我预期的结果并不容易。  
        
    result   =   SomeInt   -   1;  
        
    举例说:  
    SomeInt如果==1;  
    预期的结果result当然==0;  
        
    但是,如果SomeInt是一个全程共享的全局变量情况就不一样了。  
    C语言的"result   =   SomeInt   -   1;"  
    在实际的执行过程中,有好几条指令,在指令执行过程中,其它线程可能改变SomeInt值,使真正的结果与你预期的不一致。  
        
    所以InterlockedDecrement(&SomeInt)的执行过程是这样的  
    {  
          __禁止其他线程访问   (&SomeInt)   这个地址  
        
          SomeInt   --;  
            
          move   EAX,   someInt;   //   设定返回值,C++函数的返回值   都放在EAX中,  
        
          __开放其他线程访问   (&SomeInt)   这个地址  
    }  
        
    但是实际上只需要几条指令加前缀就可以完成,以上说明是放大的。  
        
    你也许会说,这有必要吗?   一般来说,发生错误的概率不大,但是防范总是必要的
    如果不考虑多线程  
    result   =   InterlockedDecrement(&SomeInt);  
    就是result   =   SomeInt   -   1;  
    如果SomeInt==1,result一定==0;  
        
    但是,在多线程中如果SomeInt是线程间共享的全局变量,情况就不那么简单了。  
    result   =   SomeInt   -   1;  
    在CPU中,要执行好几条指令。在指令中间有可能SomeInt被线程修改。那实际的结果就不是你预期的结果了。  
        
    InterlockedDecrement(&SomeInt)  
    放大的过程,如下:  
    {  
          __禁止其他线程访问   &SomeInt   地址;  
        
          SomeInt   --;  
            
          /////其他线程不会在这里修改SomeInt值。   !!!!!!  
        
          mov   EAX,   SomeInt;   //C++   函数返回值   总放在EAX中。  
            
          __开放其他线程访问   &SomeInt   地址;  
    }  
        
    实际的CPU执行过程只有几条加前缀的指令(586指令)  
        
    你会说,有必要吗?   出错的概率不大,但是错误总是需要防范的。当然可以用其他多线程机制实现,但是都没有这样简洁,所以Interlocked...函数有必要提供。 
     

  • 相关阅读:
    S2-001 远程代码执行漏洞
    Struts2 devMode远程代码执行漏洞检测利用
    CVE-2017-12615(Tomcat PUT方法任意写文件漏洞)
    Medium | LeetCode 343 | 剑指 Offer 14- I. 剪绳子 | 动态规划
    Medium | 剑指 Offer 38. 字符串的排列 | 回溯
    Medium | 剑指 Offer 60. n个骰子的点数 | 动态规划
    Medium | 剑指 Offer 46. 把数字翻译成字符串 | 回溯
    Medium | 剑指 Offer 59
    Hard | LeetCode 239 | 剑指 Offer 59
    Medium | 剑指 Offer 35. 复杂链表的复制
  • 原文地址:https://www.cnblogs.com/carl2380/p/1924605.html
Copyright © 2020-2023  润新知