In this code snippet, a goroutine is launched and repeatedly increments the variable i:
<code class="go">package main import "time" func main() { i := 1 go func() { for { i++ } }() <-time.After(1 * time.Second) println(i) }</code>
However, the output is always 1. This behavior can be attributed to the Go memory model and the specific implementation of this code.
The Go memory model defines the conditions under which reads of a variable in one goroutine can be guaranteed to observe values produced by writes to the same variable in a different goroutine. It emphasizes the importance of synchronization for concurrent access to shared data.
In the given code:
An aggressive compiler might delete the i statement, effectively reducing the goroutine to:
<code class="go">for {}</code>
To demonstrate that the issue stems from the lack of synchronization, consider the following code:
<code class="go">package main import ( "sync" "time" ) func main() { mx := new(sync.Mutex) i := 1 go func() { for { mx.Lock() i++ mx.Unlock() } }() <-time.After(1 * time.Second) mx.Lock() println(i) mx.Unlock() }</code>
In this case, the output is no longer 1, but a large number, as expected. The sync.Mutex provides synchronization and ensures that both goroutines access i in a controlled manner, allowing the goroutine to increment i and making the changes visible to the main routine.
The above is the detailed content of Why Does My Goroutine Incrementing a Variable Produce Unexpected Results?. For more information, please follow other related articles on the PHP Chinese website!