In this code snippet, a goroutine is launched and repeatedly increments the variable i:
package main
import "time"
func main() {
i := 1
go func() {
for {
i
}
}()
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
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.
Omitting Synchronization
In the given code:
- The assignment to i (i.e., i ) is not followed by any synchronization event, indicating that changes may not be immediately visible to other goroutines.
- The compiler may optimize this loop optimization by simplifying it to a no-op.
Optimization by the Compiler
An aggressive compiler might delete the i statement, effectively reducing the goroutine to:
for {}
Example with Synchronization
To demonstrate that the issue stems from the lack of synchronization, consider the following code:
package main
import (
"sync"
"time"
)
func main() {
mx := new(sync.Mutex)
i := 1
go func() {
for {
mx.Lock()
i
mx.Unlock()
}
}()
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.
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3