如下代码,运行时会造成死锁
func main() {
var t = make(chan int)
go func() {
for i := 1;i<=10;i++ {
t <- i
}
}()
for t1 := range t{
fmt.Println(t1)
}
fmt.Println("ok")
}
原因是:for range是阻塞式读取channel,只有channel close之后才会结束,否则会一直读取,通道里没有值了,还继续读取就会阻塞,程序就会报死锁。
改成如下即可:
func main() {
var t = make(chan int)
go func() {
for i := 1;i<=100;i++ {
t <- i
}
close(t)
}()
for t1 := range t{
fmt.Println(t1)
}
fmt.Println("ok")
}
有时会没有输出,原因是主协程已经退出了,此时我们只要加个sleep即可
golang中的channel思路就是生产者消费者,无论生产者写入数据还是消费者读取数据都是阻塞的,理解这个的思路要基于阻塞这个前提。
close(ch)
deadlock
导致这种错误的情况有两种
生产者
没有消费者消费channel中的数据,channel中的数据已经填充满了,但是还在往里写入,此刻是要阻塞等待的,由于没有消费者,这个阻塞会一直阻塞下去
消费者
生产者不再生产数据了,也就是是 channel 中会一直为空了,但是消费者还在读取channel中的数据,这个读取也是阻塞等待的,channel中不会再有数据,这个等待也是会一直等待下去