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

huangapple go评论71阅读模式
英文:

Why does fmt.Println inside a goroutine not print a line?

问题

我有以下代码:

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 {
            // 处理错误
            fmt.Println(err)
        }
        fmt.Println(str)
    }()

}

如果我不把从缓冲区读取的代码放在一个 goroutine 中,它会输出像这样的消息,这是我所期望的:

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

然而,将其放在 goroutine 中则不会打印任何内容。

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

英文:

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?

答案1

得分: 95

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

一种选择是让主goroutine阻塞读取一个通道,并在goroutine完成工作时向通道写入数据。

英文:

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.

答案2

得分: 44

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

英文:

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.

答案3

得分: 5

在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 {
        // 处理错误
        fmt.Println(err)
    }
    fmt.Println(str)
    ch <- 1
  }()
  <-ch
}
英文:

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 &quot;net&quot;
import &quot;fmt&quot;
import &quot;bufio&quot;

func main() {
conn, _ := net.Dial(&quot;tcp&quot;, &quot;irc.freenode.net:6667&quot;)

reader := bufio.NewReader(conn)
ch := make(chan byte, 1)
go func() {
    str, err := reader.ReadString(&#39;\n&#39;)
    if err != nil {
        // handle it
        fmt.Println(err)
    }
    fmt.Println(str)
    ch &lt;- 1
  }()
  &lt;-ch
}

答案4

得分: -12

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

当程序终止时,goroutine会关闭。我之前也遇到过完全相同的问题。

英文:

You need to add a time delay like time.Sleep(3 * time.Second) (this waits 3 seconds).

The goroutine closes when the program terminates. I had the exact same problem.

huangapple
  • 本文由 发表于 2013年4月26日 12:39:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/16228887.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定