Go language coroutine – Goroutine. Processes, threads, coroutines (also called lightweight threads)

This can cause some confusion when using concurrent closures. Take a look at the following program:

func main(a) {
    done := make(chan bool)

    values := []string{"a"."b"."c"}
    for _, v := range values {
        go func(a) {
            fmt.Println(v)
            done <- true(1)}}// wait for all goroutines to complete before exiting
    for _ = range values {
        <-done
    }
}
Copy the code

People may mistakenly think that A, B, and C are outputs. But what you might actually see is c, C, C. This is because each iteration of the loop uses the same instance of variable v, so each closure shares this single variable. When the closure runs, it prints the value of v when fmt.println is executed, but v may have been modified since Goroutine started. To help detect these problems before they occur, go Vet can be run.

To bind the current value of V to each closure when it is started, the inner loop must be modified to create a new variable at each iteration. One way is to pass variables to closures as arguments:

    for _, v := range values {
        go func(u string) {
            fmt.Println(u)
            done <- true
        }(v)
    }
Copy the code

In this example, the value of v is passed as an argument to the anonymous function. This value can be accessed inside the function as the variable u. It’s easier to create a new variable and use a seemingly strange declaration style that works well in Go:


    for _, v := range values {
        v := v // create a new 'v'.
        go func(a) {
            fmt.Println(v)
            done <- true(1)}}Copy the code

This strange behavior, which did not define a new variable for each iteration, now seems to have been a mistake. It may be addressed in a later release, but cannot be changed in Go 1 for compatibility.

Foreign Language translation project golang.org/doc/faq#clo…