1. 程式人生 > >多核、多處理器環境下多執行緒同步技巧

多核、多處理器環境下多執行緒同步技巧

這裡稍微講解一下。
在ThreadProc中,我們的目的仍然是要將counter加1。那麼我們先讀取counter的值,然後將該值加1後的 值儲存到一邊。然後我們就可以用自己打造的cmpxchg_64做原子操作了。如果返回值為1,說明原來的值與counter在比較時的值是完全一樣的。 比如,初始值為0,那麼在交換前counter的值沒有被其它執行緒改寫,因此仍然為0,這時就可以將加1後的值寫入counter。由於cmpxchg是 一個原子操作,因此整個比較與交換的過程是原子的,外部不會打斷此操作,並且在此操作期間,匯流排會將counter鎖住,使得其它執行緒要訪問 counter時,其所在的核都會被阻塞。
如果返回0,說明counter被讀取後交換前被修改過,那麼這裡就要重新獲得counter的值並且 在此基礎上做加1操作,然後再執行cmpxchg操作,直到最後成功。

我們可以清楚地看到,這段程式碼中沒有新增任何鎖,而且,如果正在 ThreadProc的一個執行緒被銷燬也不會影響其它執行緒的執行,從而我們根本就不需要新增開關中斷的形式來保證避免其它執行緒死鎖的問題。
另外, 大家可以在3樓程式碼中第11行插入counter++;
在 看看結果。

最後再提供一份關於Lock-Free比較好的資料:Non-blocking synchronization

其中,cmpxchg是屬於CAS機制;而在ARMv7架構中的LDREX/STREX是屬於 LL/SC機制。它們都可以用來實現Lock-Free的方法。然而LL/SC機制使用起來必須更加謹慎,因為LL和SC往往必須成對出現,中間也不該允 許被中止。所以這個機制大多架構中用的比較少。現在ARMv7以及Power架構有這個指令集,而ARMv7只有這一種方法能實現 Lock-Free。而ARMv7之前,只能使用SWP指令來實現旋鎖,SWP與XCHG功能完全一樣。