多線程讀取全局變量


  題目:

int global = 0;

// thread 1
for(int i = 0; i < 10; ++i)
global -= 1;

// thread 2
for(int i = 0; i < 10; ++i)
global += 1;

  之后global的可能的值是多少(多種可能)?

 

  這個問題考慮的是全局變量global的加減操作不是原子操作,在加減過程中有可能被打斷,從而產生的結果與預期不一樣。上述global加減操作的匯編如下

;windows下加操作
mov eax,dword ptr [globle (10A9148h)] 
add eax,1 
mov dword ptr [globle (10A9148h)],eax 

;windows下減操作
mov eax,dword ptr [globle (10A9148h)] 
sub eax,1 
mov dword ptr [globle (10A9148h)],eax 

;linux下加操作
movl global, %eax
addl $1, %eax
movl %eax, global

;linux下減操作
movl global, %eax
subl $1, %eax
movl %eax, global

  可見,不論加減都要經過global的值加載到eax,然后eax加減1,最后再寫回global中。這時如果線程1的global的值剛加載到eax中,線程2獲取到了執行權,就會出現問題。具體看下面例子。

  假設操作前global值為5。

  線程1                                                                                                                  線程2

  movl global,%eax;global值為5,%eax值為5

  addl $1,%eax;%eax值為6

                                                                   ------此時線程2獲取執行權限--------->

                                                                                                                           movl global,%eax;global值為5,%eax值為5

                                                                                                                           subl $1,%eax;%eax值為4

                                                                                                                           movl %eax,global;%eax值為4,global值為4

                                                                 <--------執行權交回線程1-------------- 

  movl %eax,global;%eax值為4,global值為4

  由上述例子可以看出,結果並非我們預計的global的值加1減1后仍保持原值,而是由5變為了4。這就是多線程下非原子操作有可能產生的問題。

  所以題目global輸出並非0一種可能。global的加減操作有可能失效,所以global的結果應分布在-10到10之間。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM