阿里云建網(wǎng)站流程谷歌seo優(yōu)化公司
在Go并發(fā)編程中,當多個 goroutine 同時讀寫共享變量時,如果沒有妥善同步,就會出現(xiàn)數(shù)據(jù)競爭(Data Race)。Go 提供了?
sync/atomic
?包,用于實現(xiàn)輕量級的原子操作,避免使用鎖所帶來的性能開銷。
一、什么是原子操作?
原子操作指的是在執(zhí)行過程中不會被任何其他操作中斷的操作。在多線程環(huán)境中,原子操作確保某個變量的讀、寫、加減等操作具有一致性和安全性。
二、常用原子操作函數(shù)
Go 的?sync/atomic
?包支持以下常用操作,主要用于?int32
、int64
、uint32
、uint64
?和?unsafe.Pointer
?等類型:
函數(shù) | 說明 |
atomic.LoadInt32(&val) | 原子讀取值 |
atomic.StoreInt32(&val, new) | 原子寫入值 |
atomic.AddInt32(&val, delta) | 原子加法(并返回新值) |
atomic.CompareAndSwapInt32(&val, old, new) | 原子比較并交換 |
同理還有?Int64 、Uint32 、Uint64 、Pointer ?版本 |
三、使用示例
示例:并發(fā)計數(shù)器
package?mainimport?("fmt""sync""sync/atomic"
)func?main()?{var?counter?int32?=?0var?wg?sync.WaitGroupfor?i?:=?0;?i?<?1000;?i++?{wg.Add(1)go?func()?{defer?wg.Done()atomic.AddInt32(&counter,?1)}()}wg.Wait()fmt.Println("Final?Counter:",?counter)?//?輸出應該為?1000
}
這個例子中我們使用?atomic.AddInt32
?來確保并發(fā)寫入是安全的,避免了?race condition
。
四、CompareAndSwap:原子級條件更新
CompareAndSwap
?是一個非常強大的函數(shù),可用于實現(xiàn)無鎖狀態(tài)切換。
var?status?int32?=?0//?嘗試將狀態(tài)從?0?改為?1
if?atomic.CompareAndSwapInt32(&status,?0,?1)?{fmt.Println("切換狀態(tài)成功")
}?else?{fmt.Println("狀態(tài)已被修改")
}
如果當前值等于期望值,就會被新值替換;否則不做任何操作,適用于狀態(tài)機、CAS 重試等場景。
五、原子 vs 鎖
方面 | 原子操作(atomic) | 鎖(Mutex/RWMutex) |
性能 | 極高(CPU級指令) | 較低(涉及調(diào)度、搶占) |
適用場景 | 簡單計數(shù)、狀態(tài)標記 | 復雜結(jié)構(gòu)同步 |
編程復雜度 | 較高,易出錯 | 較低,語義清晰 |
死鎖風險 | 無 | 存在風險 |
六、使用注意事項
- ? 原子操作僅適用于簡單變量的并發(fā)讀寫,如計數(shù)器、標志位。
- ? 不能對結(jié)構(gòu)體、map、slice 等復雜類型直接使用。
- ? 原子操作不能和普通操作混用,否則仍可能產(chǎn)生競態(tài)條件。
- ? 如需讀寫多個變量或復合結(jié)構(gòu),推薦使用?
sync.Mutex
。
七、小結(jié)
- ??
sync/atomic
?提供了高性能的原子操作,是無鎖并發(fā)的核心工具。 - ? 適合用于計數(shù)器、自旋鎖、狀態(tài)標識等場景。
- ? 不適合管理復雜共享數(shù)據(jù),不能代替所有同步手段。