【发布时间】:2021-04-05 23:01:59
【问题描述】:
我正在尝试使用两个 goroutine 在同步管理器 (1,2,3,4...) 中打印奇偶数,我很困惑为什么我的代码会导致死锁。请你帮我理解一下?
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func odd(ch chan bool){
i :=1
for i<=10{
<-ch
fmt.Println(i)
i+=2
ch<-true
}
wg.Done()
}
func even(ch chan bool){
i :=2
for i<=10{
<-ch
fmt.Println(i)
i+=2
ch <- true
}
wg.Done()
}
func main() {
ch :=make(chan bool)
wg.Add(2)
go even(ch)
go odd(ch)
ch <- true
wg.Wait()
}
O/P: 1 2 3 4 5 6 7 8 9 10 致命错误:所有 goroutine 都处于休眠状态 - 死锁!
goroutine 1 [semacquire]: sync.runtime_Semacquire(0x5844a8) /usr/local/go-faketime/src/runtime/sema.go:56 +0x45 sync.(*WaitGroup).Wait(0x5844a0) /usr/local/go-faketime/src/sync/waitgroup.go:130 +0x65 main.main() /tmp/sandbox505861393/prog.go:37 +0xcf
goroutine 6 [chan send]: main.even(0xc00005e060) /tmp/sandbox505861393/prog.go:26 +0xc5 由 main.main 创建 /tmp/sandbox505861393/prog.go:34 +0x7f
当我更改 goroutine 的顺序时,o/p 开始以奇偶方式打印,我也很难理解这一点。非常感谢您的帮助,谢谢。
【问题讨论】:
-
您知道通道上的发送和接收都被阻塞了吗?正如您的错误输出已经告诉您的那样,由于另一个 goroutine 已经终止并且没有人在通道上接收,因此其中一个 goroutine 被卡在发送中。
-
作为旁注。你不应该在同一个 goroutine 的通道上发送和接收。这不是好的做法。
标签: go deadlock channel goroutine