为什么GO例程不启动?

I wrote a simple GO program that should start 3 GO routines. However, the GO routines don't start.

Please note that the situation is not identical to the one describer within this post :

Why is my goroutine not executed?

The program should wait for the GO routines to end their execution... Thus, the program should wait forever (since the routines never stop).

package main

import (
    "fmt"
    "net"
    "os"
    "time"
    "sync"
)

func main() {

    wg := sync.WaitGroup{}

    fmt.Print("Starting 3 clients
")

    for i:=0; i<3; i++ {

        client := func(inName string) {

            fmt.Printf("Client <%s> started
", inName)

            wg.Add(1)
            conn, err := net.Dial("tcp", ":8000")
            if err != nil {
                fmt.Printf("[%s] Error while connecting to the server: %s", inName, err.Error())
                os.Exit(1)
            }

            n := 0
            sleepDuration, _ := time.ParseDuration("2s")
            for {
                message := fmt.Sprintf("[%s] > message %d
", inName, n)
                fmt.Printf("%s", message)
                _, err := conn.Write([]byte(message))
                if nil != err {
                    fmt.Sprintf("[%s] Error while writing data to the socket: %s", inName, err.Error())
                    os.Exit(1)
                }
                time.Sleep(sleepDuration)
                n++
            }
        }

        name := fmt.Sprintf("Client%d", i)
        fmt.Printf("Starting client <%s>...
", name)
        go client(name)
        fmt.Print("Done
")
    }

    wg.Wait()
}

Result:

Starting 3 clients
Starting client <Client0>...
Done
Starting client <Client1>...
Done
Starting client <Client2>...
Done

As this solution says:

It is important that the wg.Add() happens before the go statement to prevent race conditions. The following would also be correct:

So, you need to take out wg.Add(1) off inside of go routine itself and call it just before starting go routines. Also, call defer wg.Done() at the start of the function, so that, it will decrements the WaitGroup counter by one. Take a look at the code below.

package main

import (
    "fmt"
    "net"
    "os"
    "time"
    "sync"
)

func main() {

    wg := sync.WaitGroup{}

    fmt.Print("Starting 3 clients
")

    for i:=0; i<3; i++ {

        client := func(inName string) {

            defer wg.Done() // added this line

            fmt.Printf("Client <%s> started
", inName)

            conn, err := net.Dial("tcp", ":8000")
            if err != nil {
                fmt.Printf("[%s] Error while connecting to the server: %s", inName, err.Error())
                os.Exit(1)
            }

            n := 0
            sleepDuration, _ := time.ParseDuration("2s")
            for {
                message := fmt.Sprintf("[%s] > message %d
", inName, n)
                fmt.Printf("%s", message)
                _, err := conn.Write([]byte(message))
                if nil != err {
                    fmt.Sprintf("[%s] Error while writing data to the socket: %s", inName, err.Error())
                    os.Exit(1)
                }
                time.Sleep(sleepDuration)
                n++
            }
        }

        name := fmt.Sprintf("Client%d", i)
        fmt.Printf("Starting client <%s>...
", name)
        wg.Add(1) // moved this line
        go client(name)
        fmt.Print("Done
")
    }

    wg.Wait()
}