将例程与通道一起使用时出现死锁问题
Deadlock issue when using routine with channel
我在将 Go 例程与通道一起使用时遇到问题。代码如下所示:
func main() {
c := make(chan int)
var wg sync.WaitGroup
wg.Add(1)
go func (c chan int, x int) {
c <- x
fmt.Println(x)
close(c)
defer wg.Done()
}(c,10)
wg.Wait()
}
当运行代码我得到这个错误:
fatal error: all goroutines are asleep - deadlock!
我不明白为什么会出现这个问题。请帮助我理解
您的示例中有 2 个 goroutine:主 goroutine 运行 main()
函数,另一个在其中启动。主 goroutine 等待另一个 goroutine 完成(调用 wg.Done()
),其他 goroutine 阻塞在它试图在通道 c
上发送值的行中。由于没有人从那个通道接收数据,并且因为那个通道是无缓冲的,所以这个 goroutine 永远不会前进,所以你所有的 2 个 goroutine 都会永远阻塞。
注意defer wg.Done()
应该是goroutine中的第一条语句。如果是最后一个,defer
没有任何区别。
如果通道的缓冲区至少为 1,则发送操作可以继续:
c := make(chan int, 1)
输出将是(在 Go Playground 上尝试):
10
如果我们让通道不带缓冲,则必须有另一个 goroutine 从通道接收,例如:
wg.Add(1)
go func() {
defer wg.Done()
x := <-c
fmt.Println("Received:", x)
}()
然后输出将是(在 Go Playground 上尝试):
10
Received: 10
我在将 Go 例程与通道一起使用时遇到问题。代码如下所示:
func main() {
c := make(chan int)
var wg sync.WaitGroup
wg.Add(1)
go func (c chan int, x int) {
c <- x
fmt.Println(x)
close(c)
defer wg.Done()
}(c,10)
wg.Wait()
}
当运行代码我得到这个错误:
fatal error: all goroutines are asleep - deadlock!
我不明白为什么会出现这个问题。请帮助我理解
您的示例中有 2 个 goroutine:主 goroutine 运行 main()
函数,另一个在其中启动。主 goroutine 等待另一个 goroutine 完成(调用 wg.Done()
),其他 goroutine 阻塞在它试图在通道 c
上发送值的行中。由于没有人从那个通道接收数据,并且因为那个通道是无缓冲的,所以这个 goroutine 永远不会前进,所以你所有的 2 个 goroutine 都会永远阻塞。
注意defer wg.Done()
应该是goroutine中的第一条语句。如果是最后一个,defer
没有任何区别。
如果通道的缓冲区至少为 1,则发送操作可以继续:
c := make(chan int, 1)
输出将是(在 Go Playground 上尝试):
10
如果我们让通道不带缓冲,则必须有另一个 goroutine 从通道接收,例如:
wg.Add(1)
go func() {
defer wg.Done()
x := <-c
fmt.Println("Received:", x)
}()
然后输出将是(在 Go Playground 上尝试):
10
Received: 10