Golang中死锁错误问题的解决方法
Golang中死锁错误问题的解决方法
链接
我正在向我的 channel 中放入数据,并从不同的 goroutine 中取出。
在我从 channel 中取出所有需要的数据后,我遇到了死锁错误。
使用普通的 for 循环 像下面这样:
for i := 0; i < *n; i++ {
res := <-c
fmt.Printf("[%s %v]\n", res.label, res.time.Format("15: 04: 05.0000"))
}
可以正常工作,但我需要使用 range 来处理它。
知道代码有什么问题吗? 我认为问题在于找到在哪里关闭我的 channel。 链接
更多关于Golang中死锁错误问题的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
3 回复
是的,这很常见。你可以在单独的 goroutine 中等待并关闭通道:
go func() {
wg.Wait()
close(c)
}()
consumer(c)
问题在于你没有正确关闭 channel,导致 range 循环无法知道何时停止接收数据。range 会一直尝试从 channel 读取,直到 channel 被显式关闭。
在你的代码中,worker goroutine 发送完所有数据后没有关闭 channel,因此主 goroutine 中的 range c 会一直等待更多数据,造成死锁。
这是修复后的示例:
package main
import (
"fmt"
"time"
)
type result struct {
label string
time time.Time
}
func worker(c chan<- result, n int) {
defer close(c) // 关键:发送完成后关闭 channel
for i := 0; i < n; i++ {
c <- result{
label: fmt.Sprintf("worker %d", i),
time: time.Now(),
}
}
}
func main() {
c := make(chan result)
n := 5
go worker(c, n)
// 使用 range 安全地接收所有数据
for res := range c {
fmt.Printf("[%s %v]\n", res.label, res.time.Format("15:04:05.0000"))
}
}
关键修改:
- 在
worker函数中使用defer close(c),确保函数退出时关闭 channel - 发送方负责关闭 channel,而不是接收方
range c会在 channel 关闭后自动退出循环
这样修改后,range 循环会在所有数据接收完毕后正常退出,避免了死锁。

