Go knowledge points (01)-the execution sequence of the main coroutine and sub coroutines

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

  1. 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.

  1. 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.

  1. 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.WaitGroupto 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

Guess you like

Origin blog.csdn.net/wohu1104/article/details/115312953
Recommended