【问题标题】:Why does fmt.Println inside a goroutine not print a line?为什么 goroutine 中的 fmt.Println 不打印一行?
【发布时间】:2013-04-20 04:22:12
【问题描述】:

我有以下代码:

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

谁能解释为什么会这样?

【问题讨论】:

    标签: go


    【解决方案1】:

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

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

    【讨论】:

    • 感谢詹姆斯的精彩解释。我绝对认为频道是我正在寻找的。​​span>
    【解决方案2】:

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

    【讨论】:

    • 感谢您的分享,埃里克。
    【解决方案3】:

    在goroutine结束时将数据写入通道ch并从goroutine从ch读取数据可以使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
    }
    

    【讨论】:

      【解决方案4】:

      您需要添加一个时间延迟,例如time.Sleep(3 * time.Second)(这会等待 3 秒)。

      goroutine 在程序终止时关闭。我遇到了完全相同的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-17
        • 2021-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多