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

时间:2013-04-26 04:39:57

标签: go

我有以下代码:

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里面什么都不打印。

有人可以解释为什么会这样吗?

4 个答案:

答案 0 :(得分:72)

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

一个选项是让主goroutine块从一个通道读取,并在完成其工作时让goroutine写入通道。

答案 1 :(得分:33)

等待goroutines结束"的另一种常见方法是使用WaitGrouphttp://golang.org/pkg/sync/#WaitGroup。您可以对每个已启动的goroutine使用waitGroup.Add(1),然后在每个goroutine完成后使用waitGroup.Done()。在main函数中,您可以使用waitGroup.Wait(),这将等到为每个添加的goroutine调用waitGroup.Done()

答案 2 :(得分:2)

在goroutine末尾将数据写入通道ch,从goroutine中读取ch的数据可以使主函数等待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
}

答案 3 :(得分:-6)

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

程序终止时goroutine关闭。我遇到了同样的问题。