在Go語言中,避免競態條件(race condition)的關鍵是使用同步原語來確保對共享資源的訪問是互斥的。以下是一些建議和最佳實踐:
sync.Mutex
或sync.RWMutex
來確保同一時間只有一個goroutine可以訪問資源。import "sync"
var mu sync.Mutex
var sharedResource int
func updateSharedResource() {
mu.Lock()
defer mu.Unlock()
sharedResource++
}
sync/atomic
包中的原子操作函數來避免競態條件。import "sync/atomic"
var sharedResource int32
func updateSharedResource() {
atomic.AddInt32(&sharedResource, 1)
}
func updateSharedResource(ch chan int) {
ch <- 1
}
func main() {
ch := make(chan int)
go updateSharedResource(ch)
<-ch // 等待更新完成
}
sync.WaitGroup
:當你需要等待一組goroutine完成時,可以使用sync.WaitGroup
來確保所有goroutine都完成后再繼續執行。import "sync"
var wg sync.WaitGroup
func updateSharedResource() {
// ...
wg.Done()
}
func main() {
wg.Add(1)
go updateSharedResource()
wg.Wait() // 等待所有goroutine完成
}
總之,要避免競態條件,關鍵是使用Go語言提供的同步原語來確保對共享資源的訪問是互斥的。在設計并發程序時,盡量減少共享資源的使用,并使用適當的同步策略來保護這些資源。