为什么这个程序无法使用goroutine打印任何内容?

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

Why can't this program print anything using goroutine?

问题

我最近在研究谷歌的Golang,并遇到了以下问题。然后程序没有打印任何内容。但是如果我删除"go"标记,它将打印出"goroutine"和"going"两个词。

  1. package main
  2. import "fmt"
  3. func f(msg string) {
  4. fmt.Println(msg)
  5. return
  6. }
  7. func main() {
  8. go f("goroutine")
  9. go func(msg string) {
  10. fmt.Println(msg)
  11. return
  12. }("going")
  13. return
  14. }
英文:

I'm recently looking into Golang by google and I met with the following problem. Then program doesn't print anything. But if I remove the "go" notations, it will print both "goroutine" and "going".

  1. package main
  2. import "fmt"
  3. func f(msg string) {
  4. fmt.Println(msg)
  5. return
  6. }
  7. func main() {
  8. go f("goroutine")
  9. go func(msg string) {
  10. fmt.Println(msg)
  11. return
  12. }("going")
  13. return
  14. }

答案1

得分: 8

你的程序在goroutine执行之前就退出了。你可以稍微等待一下,例如通过调用time.Sleep(2 * time.Second),但这种行为被认为是不好的实践,因为你的程序可能运行时间超过2秒,然后仍然终止。

更好的方法是使用sync.WaitGroup

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. )
  6. func f(msg string, wg *sync.WaitGroup) {
  7. fmt.Println(msg)
  8. wg.Done()
  9. }
  10. func main() {
  11. var wg sync.WaitGroup
  12. wg.Add(1)
  13. go f("goroutine", &wg)
  14. wg.Add(1)
  15. go func(msg string) {
  16. fmt.Println(msg)
  17. wg.Done()
  18. }("going")
  19. wg.Wait()
  20. }
英文:

You program exits before the goroutines is executed. You could wait a little bit, for example by calling time.Sleep(2 * time.Second), but such behaviour is considered bad practice, since your program could run longer than 2 seconds and would then terminate nonetheless.

A better approach is to use sync.WaitGroup:

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. )
  6. func f(msg string, wg *sync.WaitGroup) {
  7. fmt.Println(msg)
  8. wg.Done()
  9. }
  10. func main() {
  11. var wg sync.WaitGroup
  12. wg.Add(1)
  13. go f("goroutine", &wg)
  14. wg.Add(1)
  15. go func(msg string) {
  16. fmt.Println(msg)
  17. wg.Done()
  18. }("going")
  19. wg.Wait()
  20. }

答案2

得分: 5

你的代码需要在退出之前等待例程完成。一种好的方法是传入一个通道,例程使用该通道来发出完成信号,然后在主代码中等待。请参考下面的代码。

这种方法的另一个优点是它允许/鼓励你根据返回值进行适当的错误处理。

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func f(msg string, quit chan int) {
  6. fmt.Println(msg)
  7. quit <- 0
  8. return
  9. }
  10. func main() {
  11. ch1 := make(chan int)
  12. ch2 := make(chan int)
  13. go f("goroutine", ch1)
  14. go func(msg string, quit chan int) {
  15. fmt.Println(msg)
  16. quit <- 0
  17. return
  18. }("going", ch2)
  19. <-ch1
  20. <-ch2
  21. return
  22. }
英文:

Your code needs to wait for the routines to finish before exiting. A good way to do this is to pass in a channel which is used by the routine to signal when it's done and then wait in the main code. See below.

Another advantage of this approach is that it allows/encourages you to perform proper error handling based on the return value.

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. )
  5. func f(msg string, quit chan int) {
  6. fmt.Println(msg)
  7. quit &lt;- 0
  8. return
  9. }
  10. func main() {
  11. ch1 := make(chan int)
  12. ch2 := make(chan int)
  13. go f(&quot;goroutine&quot;, ch1)
  14. go func(msg string, quit chan int) {
  15. fmt.Println(msg)
  16. quit &lt;- 0
  17. return
  18. }(&quot;going&quot;, ch2)
  19. &lt;-ch1
  20. &lt;-ch2
  21. return
  22. }

huangapple
  • 本文由 发表于 2014年2月14日 01:23:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/21761172.html
匿名

发表评论

匿名网友

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

确定