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
}