[TOC] # 简介 出现死锁的情况 * 单go协程自己死锁 * go协程之间channel访问顺序导致死锁 * 多go协程,多channel交叉死锁 尽量不要将读写锁和互斥锁和channel混用,有可能造成隐式死锁,还不报错 # 单go协程自己死锁 channel至少在2个协程中进行 ~~~ func main() { s:= make(chan int) //写入channel,写端阻塞,阻塞当前,下面就全部阻塞了,就没机会执行了 s<-11 //他能解锁,但是已经被阻塞了 m := <-s fmt.Println(m) } ~~~ 输出 ~~~ fatal error: all goroutines are asleep - deadlock! ~~~ # go协程之间channel访问顺序导致死锁 使用一端写的时候,保证另一端有机会读取,代码写下面 ~~~ func main() { ch:= make(chan int) //读取,阻塞,阻塞了下面就不执行了,除非把他放在go func的下面 m := <-ch fmt.Println(m) go func() { //他能解锁,但是主程序在之前就阻塞了 ch <- 11 }() } ~~~ # 多go协程,多channel交叉死锁 ~~~ func main() { ch1 := make(chan int) ch2 := make(chan int) go func() { //子 for { select { //读操作阻塞 case num := <-ch1: //写 ch2 <- num } } }() for { //主 select { //读 case num := <-ch2: //写 ch1 <- num } } } ~~~