一次无聊的写码中,遇到了一个死锁的问题,百思不解特意花了半天的时间研究了一下。过程是这样的:
package main
import (
"fmt"
)
func main() {
ch := make(chan int, 5)
go func() {
ch <- 1
ch <- 2
// 注释掉 range 操作会产生死锁
//close(ch)
}()
fmt.Println("cap:", cap(ch), "len:", len(ch))
for i := range ch {
fmt.Println(i)
}
//<-ch
fmt.Println("cap:", cap(ch), "len:", len(ch))
}
// output
cap: 5 len: 0
1
fatal error: all goroutines are asleep - deadlock!
2
goroutine 1 [chan receive]:
main.main()
/Users/ott002/go/src/t.go:19 +0x201
Process finished with exit code 2
出现 deadlock,奇怪中,变换了许多姿势,仍然依旧。
精简一下代码
package main
func main() {
ch := make(chan int, 5)
//ch <- 1
// deadlock
<-ch
}
便于分析问题。
何谓死锁? 操作系统有讲过的,所有的线程或进程都在等待资源的释放。如上的程序中, 只有一个goroutine, 所以当你从通道获取数据的话,会锁死信道, 并且阻塞当前 goroutine 等待数据的存入, 也就是所有的goroutine(其实就main线一个)都在等待信道的存入,也就是产生死锁咯。