What is the output of the following code?
package main
import (
"fmt"
)
func main() {
for i := 0; i < 10; i++ {
go func() {
fmt.Println(i)
}()
}
}
What is the output of running this code? There may be the following answers
- There is a high probability that nothing will be output
The reason is: As long as the main coroutine, that is, the main process, finishes executing, other Go coroutines will end immediately, and the main coroutine, which is the Go program, will not wait for other Go coroutines.
At this time, the Go is started due to the for loop. It is entirely possible that the coroutine is still running, resulting in no output of any content.
- There is a small probability of 10 out of 10
The reason is: If the 10 coroutines started by the for loop are running before the main coroutine is executed, the scheduling of the coroutine takes a certain amount of time, and usually this time is greater than the time of the
for loop, so wait 10 When the coroutine is started, the for loop has been executed until the last variable i=10, so 10 10s will be printed.
- The small probability may be out of order from 1 to 9, etc.
Reason: If the Go goroutine starts quickly, the goroutine will start immediately every time a variable is executed in the for loop, and then prints ranging from 1 to 9. The final reason
is still related to the scheduling mechanism of the Go goroutine .
So the question is, if you want the sub-coroutine to exit after the execution is complete, what can be done?
We can use sync.WaitGroup
to achieve, look at the code below
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1) // 每启动一个协程就加 1
go func() {
defer wg.Done() // 协程退出时自动减 1
fmt.Println(i)
}()
}
wg.Wait() // 等待所有协程执行完毕
}
The output result is:
10
10
10
10
10
10
10
10
10
10
If you want it to print 0,1,2,3,4... etc., how do you need to modify the code?
You only need to pass in the corresponding variable when calling the coroutine function, as shown in the following code:
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(n int) {
defer wg.Done()
fmt.Println(n)
}(i) // 传入外面循环变量的值
}
wg.Wait()
}
Reference:
https://mp.weixin.qq.com/s/gqqAazWUCp1ZtK7PebJe3g