【问题标题】:Goroutine and for loopGoroutine 和 for 循环
【发布时间】:2015-06-28 02:08:04
【问题描述】:

我要做的就是向通道发送一个值并从main()函数返回,并在我从通道ch收到一个值后立即退出程序。

但这会一直运行下去:

ch := make(chan int)

for {
    go func() {
        ch <- 1
    }()
}

<-ch

当我从通道接收到一个值后,如何使用这个for 循环返回?

为什么这会永远运行?

去游乐场链接在这里

http://play.golang.org/p/EvmT6Pw96Y

【问题讨论】:

  • 你为什么使用for循环?
  • 只是实验性的。我只是想启动 goroutines 并退出主程序

标签: concurrency go parallel-processing goroutine


【解决方案1】:

由于for 循环永远运行,您的代码将永远运行。在for 循环之后从ch 接收永远不会到达。

如果您希望代码在某个时间退出,则必须在某个时间结束 for 循环,例如让它只运行一定数量的迭代:

for i := 0; i < 5; i++ {
    ...
}

因此,如果您只运行 5 次迭代(如在我的示例中),则在从 ch 接收的 for 循环之后,如果其他 goroutine 尚未运行,则可能会阻塞(因为 ch 未缓冲),并且至少有一个启动的 goroutine 将被执行,它在通道上发送一个值,这可能会触发主 goroutine 继续(因为它的阻塞操作不再阻塞)。

还要注意Go Memory Model 只保证某些事件在其他事件之前发生,你不能保证 2 个并发的 goroutines 是如何执行的。您无法保证在 for 循环中启动的 goroutine 将在主 goroutine 在接收来自 ch 时被阻塞之前开始执行。

通常当一个 goroutine 被阻塞(例如阻塞通道接收操作)时,运行时可能会安排另一个 goroutine 运行。

【讨论】:

  • 谢谢,我在想 for-loop 中的第一个 goroutine 会在后台启动,如果我从他们那里收到一个,主程序就会退出。
  • 从通道读取永远不会到达,因为主例程在无限循环中旋转,启动无限数量的协程。该程序应该会因内存不足而崩溃或在几秒钟后冻结您的计算机,因为它一直在分配内存。
猜你喜欢
  • 1970-01-01
  • 2016-12-13
  • 2019-02-20
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 2021-07-30
  • 2021-12-27
  • 2019-11-06
相关资源
最近更新 更多