为什么goroutine中的fmt.Println无法打印行?


70

我有以下代码:

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中不会打印任何内容。

有人可以解释为什么吗?

Answers:


79

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

一种选择是从通道读取主goroutine块,并在完成工作后将goroutine写入通道。


2
谢谢詹姆斯的出色解释。我绝对认为频道是我想要的。
Ryan Bigg

36

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


谢谢您的分享,Erik。
瑞安·比格

3

ch在goroutine的末尾将数据写入通道并从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
}

-9

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

程序终止时,goroutine关闭。我有同样的问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.