我正在练习通过同时将计算分成 100 个组来计算阶乘的挑战,我在 WaitGroups 上解决了很多问题,但仍然在函数中calculateFactorial
我在通道部分的范围上遇到了死锁。希望有人能指出这里的问题,谢谢。
更新:它通过简单地将 更改为缓冲通道解决了上述代码中的问题。
你永远不应该仅仅为了修复死锁而添加缓冲。如果您的程序死锁,从零缓冲开始并仔细考虑依赖关系,修复起来要容易得多。然后在您知道不会死锁时添加缓冲。
那么谁能帮我弄清楚如何不为此使用缓冲通道?是否可以?
此外,我对导致死锁的确切原因做了一些研究。
如果通道是无缓冲的,则发送方会阻塞,直到接收方收到该值。如果通道有缓冲区,发送方只会阻塞直到值被复制到缓冲区;如果缓冲区已满,这意味着等待某个接收者检索到一个值。
否则说:
当通道已满时,发送方等待另一个 goroutine 通过接收来腾出一些空间
你可以看到一个无缓冲的通道总是满的:必须有另一个 goroutine 来接收发送者发送的内容。
所以在我原来的情况下,可能导致僵局的原因可能是:
频道上的范围没有接收到?
通道上的范围未在单独的 go 例程中接收。?
没有oneResult
正确关闭,所以 range over channel 不知道尽头在哪里?
对于数字 3,我不知道关闭 before range over 是否有任何错误oneResult
,因为这种模式出现在互联网上的许多示例中。如果是 3 号,是不是等待组有问题?
我得到了另一篇与我的情况非常相似的文章,他使用for { select {} }
无限循环作为 range over 的替代方法,似乎解决了他的问题。
go func() {
for{
select {
case p := <-pch:
findcp(p)
}
}
}()
第 2 课 — 无缓冲通道无法保存值(是的,它就在名称“无缓冲”中),因此无论发送到该通道的什么,都必须立即由其他代码接收。接收代码必须在不同的 goroutine 中,因为一个 goroutine 不能同时做两件事:它不能发送和接收;它必须是一个或另一个。
慕哥9229398
梵蒂冈之花
相关分类