Home >Backend Development >Golang >How to Avoid Data Races When Launching Goroutines in Go?
Data Race in Concurrent Go Routine
This code demonstrates a data race issue in a concurrent Go routine:
package main import ( "fmt" "time" ) type field struct { name string } func (p *field) print() { fmt.Println(p.name) } func main() { data := []field{{"one"}, {"two"}, {"three"}} for _, v := range data { go v.print() } <-time.After(1 * time.Second) }
Issue:
The code prints "three" three times instead of printing "one", "two", and "three" in any order. This is because there is a data race.
Explanation:
Implicitly, the code takes the address of the variable v when evaluating arguments to the goroutine function. The goroutine function v.print() is equivalent to (&v).print(). The loop changes the value of v, and when the goroutines execute, they happen to have the last value of the loop ("three").
Fixes:
There are several ways to fix this data race:
for _, v := range data { v := v // short variable declaration of new variable `v`. go v.print() }
data := []*field{{"one"}, {"two"}, {"three"}} // note '*' for _, v := range data { go v.print() }
data := []field{{"one"}, {"two"}, {"three"}} // note '*' for i := range data { v := &data[i] go v.print() }
for _, v := range data { go func(v field) { v.print() // take address of argument v, not range variable v. }(v) }
The above is the detailed content of How to Avoid Data Races When Launching Goroutines in Go?. For more information, please follow other related articles on the PHP Chinese website!