C++服務器開發之筆記三


為什么需要原子性操作?

我們考慮一個例子:
(1)x++這個常見的運算符在內存中是怎樣操作的?
從內存中讀x的值到寄存器中,對寄存器加1,再把新值寫回x所處的內存地址

若是有兩個線程同時對同一個變量++,就會出現問題,如下:

time      Thread 1      Thread 2
0      load eax, x
1                   load eax, x
2      add eax, 1  
3                   add eax, 1
4      store x, eax
5                   store x, eax

我們希望的結果是x+2,但結果應該是x+1,原因就是不是原子操作,解決方法有兩個:

一 加鎖,但鎖競爭是高性能服務器的殺手,所以這里不能用。

二 gcc原子性操作:

// 原子自增操作 
//*ptr+value type __sync_fetch_and_add (type *ptr, type value) // 原子比較和交換(設置)操作
// if(*ptr==oldval) *ptr=newval,函數返回true,返回失敗,不設置。 type __sync_val_compare_and_swap (type *ptr, type oldval type newval) bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval) // 原子賦值操作 type __sync_lock_test_and_set (type *ptr, type value) 使用這些原子性操作,編譯的時候需要加-march=cpu-type

無鎖隊列實現
http://coolshell.cn/articles/8239.html

服務器開發中,volatile經常用到:

volatile的作用: 作為指令關鍵字,確保本條指令不會因編譯器的優化而省略,且要求每次直接讀值。簡單地說就是防止編譯器對代碼進行優化

當要求使用volatile 聲明的變量的值的時候,系統總是重新從它所在的內存讀取數據,而不是使用保存在寄存器中的備份。即使它前面的指令剛剛從該處讀取過數據。而且讀取的數據立刻被保存


免責聲明!

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



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