為什么需要原子性操作?
我們考慮一個例子:
(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 聲明的變量的值的時候,系統總是重新從它所在的內存讀取數據,而不是使用保存在寄存器中的備份。即使它前面的指令剛剛從該處讀取過數據。而且讀取的數據立刻被保存