程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> InterlockedIncrement函數詳解

InterlockedIncrement函數詳解

編輯:C++入門知識

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。

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...函數有必要提供。



摘自 踏雪無痕

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved