多執行緒迴圈控制欄位失效造成死迴圈的坑

Bennettz發表於2024-05-14

程式設計的時候遇到一個場景:

  A,B兩個執行緒,B是一個while(flag),有個控制欄位flag,剛開始是true

  B會一直迴圈,A某個情況回把flag置為false,但是如果B的迴圈裡什麼都沒幹,就一直不退出,陷入死迴圈

  本來以為是哪裡邏輯寫錯了,於是在B裡面加入了一個printf,沒想到結果就能正常退出了

當時覺得很奇怪,推測可能是cpu的原因,因為cpu死迴圈時候佔用率100%可能無法更新快取中的內容,

推測呼叫printf修復的原因是printf進行系統呼叫後重新整理了快取。

不過後來學習後發現x86架構沒有invalid佇列,A執行緒更改flag刷入記憶體後,B執行緒應該能立馬感知到變化,並讓本地快取失效

最後諮詢了同事,發現是編譯器的問題。

如果迴圈裡什麼都不寫,就會先獲取flag到暫存器,以後每次迴圈判斷時直接比較暫存器的值

如果迴圈里加上一些東西,或者flag加上volatile關鍵字,就不會有這個問題,迴圈判斷每次都取記憶體的值

相關文章