为什么fmt.Println在goroutine中不打印行?

我有以下代码:

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) }() } 

如果我没有在goroutine中从缓冲区中读取的代码,它会输出这样的消息,这是我期望发生的事情:

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

但是,在一个goroutine里面,什么也不打印。

有人可以解释为什么吗?

main()函数完成后,程序将退出。 这可能发生在您的goroutine有时间运行并打印输出之前。

一种select是让主要的goroutine块从一个频道读取,并在完成其工作时将该goroutine写入频道。

另一个常见的等待goroutines完成的方法是http://golang.org/pkg/sync/#WaitGroup 。 你可以为每个goroutine启动waitGroup.Add(1) ,然后在goroutine完成后waitGroup.Wait() ,而main可以waitGroup.Wait() ,它会阻塞,直到waitGroup.Done()被调用每个添加。

在goroutine结束时将数据写入通道ch ,从goroutine中读取数据可以使main函数等待goroutine打印消息。

这里是一个例子:

 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 } 

如上所述,main()函数将在goroutine有机会运行之前退出。 Goroutines作为轻量级线程运行在自己的时间。 为了debugging我通常使用的技巧,就是在我的goroutine之后添加一个睡眠,足够长的时间让我的goroutine完成。 这是一个非常基本的例子:

 package main import ( "fmt" "time" ) func main() { fmt.Println("Hello gopher!") go print_nums(10) time.Sleep(time.Millisecond * 100) // if i take this line out all i will see is hello and bye gopher! fmt.Println("Bye gopher!") } func print_nums(num int) { i := 0 for i < num { fmt.Println(i) i++ } } 

您需要添加像time.Sleep(3 * time.Second) (这等待3秒)的时间延迟。

当程序终止时,goroutineclosures。 我有同样的问题。