How Golang Concurrently Shares Variables
This discussion centers around understanding how variables are shared between multiple goroutines in Go. Consider the following code:
<code class="go">package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) x := i go func() { defer wg.Done() fmt.Println(x) }() } wg.Wait() fmt.Println("Done") }</code>
Upon execution, the expected output is obtained:
4 0 1 3 2
But when a subtle modification is made to the code:
<code class="go">package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() fmt.Println(i) }() } wg.Wait() fmt.Println("Done") }</code>
The resulting output is unexpectedly uniform:
5 5 5 5 5
Explanation
The key distinction lies in the variables' scope within goroutines.
In the first code snippet, each iteration of the loop creates a new variable x and passes its value to the goroutine. When the goroutine executes, it has a local copy of x and prints its initial value. Thus, the expected output is obtained.
However, in the second code snippet, all goroutines share a single variable i. When the goroutine executes, it retrieves the final value of i after the loop has completed. Consequently, all goroutines output the same value, 5.
Implications and Best Practices
This behavior highlights the critical importance of variable scope when using goroutines. To ensure thread-safe execution, it is essential to consider the scope of variables and leverage synchronization primitives like wait groups (as demonstrated in both code snippets) when necessary.
The above is the detailed content of Why do Golang Goroutines Output the Same Value When Sharing Variables?. For more information, please follow other related articles on the PHP Chinese website!