Home >Backend Development >Golang >How to Avoid Data Races When Launching Goroutines in Go?

How to Avoid Data Races When Launching Goroutines in Go?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-08 17:37:11227browse

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:

  • Create a new variable within the loop:
for _, v := range data {
    v := v        // short variable declaration of new variable `v`.
    go v.print()
}
  • Use a slice of pointers:
data := []*field{{"one"}, {"two"}, {"three"}} // note '*'
for _, v := range data {
    go v.print()
}
  • Use the address of the slice element:
data := []field{{"one"}, {"two"}, {"three"}} // note '*'
for i := range data {
    v := &data[i]
    go v.print()
}
  • Pass the range variable as an argument to an anonymous function:
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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn