Why does fmt.Println inside a goroutine not print a line?

I have the following code:

package main

import "net"
import "fmt"
import "bufio"

func main() {
    conn, _ := net.Dial("tcp", "irc.freenode.net:6667")

    reader := bufio.NewReader(conn)
    go func() {
        str, err := reader.ReadString('\n')
        if err != nil {
            // handle it
            fmt.Println(err)
        }
        fmt.Println(str)
    }()

}

If I don't have the code that reads from the buffer in a goroutine, it outputs a message like this, which is what I expect to happen:

:zelazny.freenode.net NOTICE * :*** Looking up your hostname...

However, having it inside a goroutine prints nothing.

Can someone explain why that is?


Your program will exit when the main() function finishes. This is likely to happen before your goroutine has time to run and print its output.

One option would be to have the main goroutine block reading from a channel, and have the goroutine write to the channel when it has completed its work.


Another common way to "wait for a goroutines end", is using WaitGroup: http://golang.org/pkg/sync/#WaitGroup . You can use waitGroup.Add(1) for each started goroutine, then use waitGroup.Done() in each goroutine after it finishes. In the main function you can use waitGroup.Wait() and this will wait until waitGroup.Done() has been called for each added goroutine.


Write data to a channel ch at the end of goroutine and read data from ch out of goroutine can make the main function waiting for goroutine print message.

Here is an example:

package main

import "net"
import "fmt"
import "bufio"

func main() {
conn, _ := net.Dial("tcp", "irc.freenode.net:6667")

reader := bufio.NewReader(conn)
ch := make(chan byte, 1)
go func() {
    str, err := reader.ReadString('\n')
    if err != nil {
        // handle it
        fmt.Println(err)
    }
    fmt.Println(str)
    ch <- 1
  }()
  <-ch
}