造成死锁的原因
- 当Go协程给一个信道发送数据时,正常来说会有其他Go协程来接受数据,如果没有的话,程序就会在运行时触发panic,形成死锁,同理,当又Go协程等着从一个信道接受数据时,我们期望其他的Go协程会向该信道写入数据,要不然程序就会触发panic
- 在未初始化的信道上发送或者接受数据
造成死锁的错误例子
读写不完整
在主线程会造成触发panic,在协程内会造成永久堵塞
主线程内
package main
func main(){
c := make(chan int)
<-c
}
运行时结果:
协程内
package main
import(
"fmt"
"time"
)
func main(){
c := make(chan int)
go func(c chan int){
fmt.Println("into goroutine")
c <-5
fmt.Println("end goroutine")
}(c)
time.Sleep(1 * time.Second)
fmt.Println("exit")
}
运行结果:
可以看到协程内在代码在执行到c<-5时阻塞了,后面的代码无法继续执行了
在同一个协程内先写入在读也是不行的。必须要有其他协程读或者写
使用了未初始化的channel
package main
import(
"fmt"
"time"
)
func main() {
var ch chan int // 未初始化,值为 nil
go func(i int) {
ch <- i
}(1)
fmt.Println("Result: ", <-ch)
time.Sleep(2 * time.Second)
}