原 4.5-4 併發技術9:原子操作
阿新 • • 發佈:2019-01-13
概述
- sync/atomic包下提供了原子操作的系列API
- 官方文件的解釋是:
atomic包提供了底層的原子級記憶體操作,對於同步演算法的實現很有用。
這些函式必須謹慎地保證正確使用。除了某些特殊的底層應用,使用通道或者sync包的函式/型別實現同步更好。
應通過通訊來共享記憶體,而不通過共享記憶體實現通訊。
- 它是使用互斥鎖進行同步操作的一種替代方案
- 原子操作由底層硬體支援,而鎖則由作業系統提供的API實現
- 若實現相同的功能,原子操作通常會更有效率
- 包括對6種基本資料型別的載入、賦值、增減、重新賦值、併發安全地重新賦值5種操作
- 這六種基本資料型別是:int32,int64,uint32,unit64,uintptr,unsafe.Pointer
- 所以原子操作的缺點是:無法支援所有資料型別
API例項
API都非常淺顯易懂,其要點是:對基本資料型別的操作效率要由於鎖
func main() { var a int64 = 123 //value := atomic.LoadInt64(&a) //fmt.Println(value)//123 ////保證將456賦值到a的地址中(期間a一定不會被其它人訪問) //atomic.StoreInt64(&a,456) //fmt.Println(a)//456 // 增減操作 //new := atomic.AddInt64(&a, 2) //fmt.Println(a,new)//125 // 重新賦值 //old := atomic.SwapInt64(&a, 456) //fmt.Println(old,a)//123,456 // 確認a沒有被併發修改的情況下重新賦值 //swapped := atomic.CompareAndSwapInt64(&a, 123, 456) //fmt.Println(swapped,a)//true 456 /*模擬a被併發修改了*/ a = 321 //確保a(原值為123)在沒有併發修改的情況下被重新賦值為456 swapped := atomic.CompareAndSwapInt64(&a, 123, 456) fmt.Println(swapped,a)//false 321 }