How to Fix Race Condition in Go: Simple Guide
sync.Mutex or channels to control access and ensure only one goroutine modifies the data at a time.Why This Happens
A race condition occurs when two or more goroutines try to read and write the same variable at the same time without coordination. This causes unpredictable results because the order of operations is not controlled.
package main import ( "fmt" "time" ) var counter int func increment() { counter = counter + 1 } func main() { for i := 0; i < 1000; i++ { go increment() } // Wait for goroutines to finish time.Sleep(time.Second) fmt.Println("Counter:", counter) }
The Fix
Use sync.Mutex to lock the shared variable while a goroutine is updating it. This ensures only one goroutine can change the variable at a time, preventing race conditions.
package main import ( "fmt" "sync" "time" ) var counter int var mu sync.Mutex func increment() { mu.Lock() counter = counter + 1 mu.Unlock() } func main() { for i := 0; i < 1000; i++ { go increment() } // Wait for goroutines to finish time.Sleep(time.Second) fmt.Println("Counter:", counter) }
Prevention
Always protect shared data with synchronization tools like sync.Mutex or use channels to communicate between goroutines safely. Use the go run -race command to detect race conditions during development. Writing tests and keeping shared state minimal also helps avoid these bugs.
Related Errors
Other concurrency issues include deadlocks, where goroutines wait forever for locks, and livelocks, where goroutines keep changing state without progress. Fix these by careful lock ordering and avoiding holding locks while waiting.