goroutine发生死锁的情况
目录
如果使用channel之前没有make,会出现dead lock错误。
至于为什么,等待研读源码补充
func main() {
var x chan int
go func() {
x <- 1
}()
<-x
}
/*
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive (nil chan)]:
main.main()
/Users/kltao/code/go/examples/channl/channel1.go:11 +0x60
goroutine 4 [chan send (nil chan)]:
main.main.func1(0x0
*/
关闭channel的时候可能会发生panic,而不是死锁
-
重复关闭 channel 会导致 panic。
func main() { c := make(chan int) go func() { for i := 0; i < 100; i++ { fmt.Println(<-c) } }() close(c) close(c) time.Sleep(time.Second) } /* panic: close of closed channel */
-
向关闭的 channel 发送数据会 panic。
func main() { c := make(chan int) go func() { for i := 0; i < 100; i++ { fmt.Println(<-c) } }() close(c) c <- 11 time.Sleep(time.Second) } /* panic: send on closed channel */
-
从关闭的 channel 读数据不会 panic,读出 channel 中已有的数据之后再读就是 channel 类似的默认值,比如 chan int 类型的 channel 关闭之后读取到的值为 0。
func main() { c := make(chan int) go func() { for i := 0; i < 100; i++ { fmt.Println(<-c) } }() close(c) time.Sleep(time.Second) }
对于上面的第三点,我们需要区分一下:channel 中的值是默认值还是 channel 关闭了。可以使用 ok-idiom 方式,这种方式在 map 中比较常用。val, ok := <-ch
写数据之前,没有其他协程阻塞接收并且没有缓冲可以存,会发生dealock
func main() {
c := make(chan int)
//c := make(chan int, 1) // 这里不会deadlock
c <- 11
go func() {
for i := 0; i < 100; i++ {
fmt.Println(<-c)
}
}()
close(c)
time.Sleep(time.Second)
}
/*
fatal error: all goroutines are asleep - deadlock!
*/
© 2017-2020 版权属于 QXQZX &
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步