Go Concurrency: Exploring the Surprising Behavior of Anonymous Function in a for Loop
In this exploration, we'll shed light on an unexpected behavior exhibited by Go concurrency when using a for loop and anonymous functions.
Problem:
Imagine running the following code snippet to test concurrency using sync.WaitGroup:
func main() { var wg sync.WaitGroup for i := 1; i <= 5; i++ { wg.Add(1) go func() { fmt.Println(i) time.Sleep(time.Second * 1) wg.Done() }() } wg.Wait() }
Surprisingly, the output observed was: 6, 6, 6, 6, 6, instead of the anticipated sequence: 1, 2, 3, 4, 5.
Explanation:
To comprehend this behavior, we refer to the Go FAQ on "What happens with closures running as goroutines?". In this scenario, the goroutines were not scheduled until after the for loop completed. Consequently, at that point, i had advanced to 6. When the goroutines executed, they all printed the captured value of i, which was 6.
Passing i as an argument to the anonymous function effectively created a copy of the current value, capturing the value at the time of the call. This explains the expected behavior observed in the modified version of the code.
The above is the detailed content of Why Does My Go Concurrency Code Print 6 Six Times Instead of 1 Through 5?. For more information, please follow other related articles on the PHP Chinese website!