【问题标题】:Why is my goroutine not executed? [duplicate]为什么我的 goroutine 没有执行? [复制]
【发布时间】:2014-08-17 00:55:42
【问题描述】:

我正在学习 Go,我想尝试 goroutine 和通道。

这是我的代码:

package main
import "fmt"
func main(){

messages := make(chan string,3)

messages <- "one"
messages <- "two"
messages <- "three"

go func(m *chan string) {
    fmt.Println("Entering the goroutine...")
    for {
        fmt.Println(<- *m)
    }
}(&messages)

fmt.Println("Done!")
}

结果如下:

Done!

我不明白为什么我的 goroutine 从未被执行。 “进入 goroutine”没有打印出来,我也没有任何错误信息。

【问题讨论】:

    标签: go


    【解决方案1】:

    事实上,你的 goroutine 启动了,但在做任何事情之前就结束了,因为你的程序在打印 Done! 后立即停止:goroutines 的执行独立于主程序,但会与程序相同地停止。所以基本上,你需要一些过程来让程序等待它们。它可能是另一个等待大量消息、sync.WaitGroup 或其他技巧的通道。

    你应该阅读golang博客中优秀的post about concurrency in go

    【讨论】:

      【解决方案2】:

      您的 Goroutine 没有足够的时间执行,因为 main 函数在打印 Done! 后退出。

      你需要做一些事情让程序等待 Goroutine。

      最简单的方法是在末尾添加time.Sleep()

      package main
      
      import (
          "fmt"
          "time"
      )
      
      func main() {
      
          messages := make(chan string, 3)
      
          messages <- "one"
          messages <- "two"
          messages <- "three"
      
          go func(m *chan string) {
              fmt.Println("Entering the goroutine...")
              for {
                  fmt.Println(<-*m)
              }
          }(&messages)
          time.Sleep(5 * time.Second)
          fmt.Println("Done!")
      }
      

      进入 goroutine...
      一个
      两个

      完成!

      Playground

      虽然这可行,但除了 goroutine 之外,建议使用通道或 sync 包中的函数来同步并发代码。

      例子:

      package main
      
      import (
          "fmt"
      )
      
      func main() {
      
          messages := make(chan string, 3)
          go func(m chan string) {
              defer close(m)
              fmt.Println("Entering the goroutine...")
              messages <- "one"
              messages <- "two"
              messages <- "three"
          }(messages)
          for message := range messages {
              fmt.Println("received", message)
          }
          fmt.Println("Done!")
      }
      

      进入 goroutine...
      收到一个
      收到两个
      收到三个
      完成!

      Playground

      【讨论】:

      • 睡眠有效,但可能是最糟糕的解决方案。在实际情况下几乎没用。
      • @Elwinar,是的,但它说明了为什么 OP 没有看到他们所期望的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-31
      • 1970-01-01
      • 1970-01-01
      • 2016-09-12
      • 2021-06-18
      相关资源
      最近更新 更多