当前位置:网站首页>读写关闭的channel是啥后果?
读写关闭的channel是啥后果?
2022-07-04 17:32:00 【小锟哥哥】
在 go 的面试中,最常问到的知识点无疑是 channel 了。
当 channel 关闭后再去读取数据会出现啥情况,最经常被问到。
一、正常的 channel
首先我们先来一段正常操作的代码:
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
for item := range ch {
fmt.Println(item)
}
这段代码应该非常熟悉,这样写是否有问题呢?
执行后的结果:
$ go run n.go
1
2
3
fatal error: all goroutines are asleep - deadlock!
如果一个 channel 不在某个协程里面关闭的话,我们的 for range 就会报死锁的错误。
二、关闭后再读取
1、使用 for range 读取关闭后的 channel
现在我们在 for range 之前关闭下这个 channel,看会出现啥情况:
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)
// 如果不关闭会报死锁 fatal error: all goroutines are asleep - deadlock!
for item := range ch {
fmt.Println(item)
}
这样写代码会出现啥问题呢?
$ go run n.go
1
2
3
啥错也没有,正常的读取。
2、直接独立取值
下面我们换直接独立取值的方式:
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)
item, state := <-ch // state 为是否读到有值
fmt.Println(item, state)
state 会返回是否取到了值,这段代码的执行结果是取到第一个值:
$ go run n.go
1 true
如果我们反复读取呢?
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)
<-ch
<-ch
<-ch
item, state := <-ch // state 为是否读到有值
fmt.Println(item, state) //全部读完值之后,再读也不会报错,只会取到零值
我前面读取 3 次,把里面的数据读取完毕后,再读取得到就是零值了。
$ go run n.go
0 false
所以结论是:如果 channel 有元素还未读,会正确读出来,哪怕他已经关闭了。
三、往里面写值呢?
最后一起来看下,当 channel 关闭后,往里面写值会怎样?
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)
ch <- 4
这段代码执行后的结果:
$ go run n.go
panic: send on closed channel
会报 panic,具体原因我们可以看 go 的源码,路径为:src/runtime/chan.go

边栏推荐
- 奥迪AUDI EDI INVOIC发票报文详解
- Nature microbiology | viral genomes in six deep-sea sediments that can infect Archaea asgardii
- 力扣刷题日记/day7/6.30
- [cloud voice suggestion collection] cloud store renewal and upgrading: provide effective suggestions, win a large number of code beans, Huawei AI speaker 2!
- Interpretation of SIGMOD '22 hiengine paper
- Scala基础教程--18--集合(二)
- Li Kou brush question diary /day4/6.26
- What if the self incrementing ID of online MySQL is exhausted?
- 力扣刷題日記/day6/6.28
- An example of multi module collaboration based on NCF
猜你喜欢
[go language question brushing chapter] go conclusion chapter | introduction to functions, structures, interfaces, and errors
力扣刷題日記/day6/6.28
Scala basic tutorial -- 18 -- set (2)
神经网络物联网平台搭建(物联网平台搭建实战教程)
力扣刷题日记/day5/2022.6.27
力扣刷题日记/day2/2022.6.24
Microservice architecture debate between radical technologists vs Project conservatives
Halcon模板匹配
Scala基础教程--13--函数进阶
Li Kou brush question diary /day2/2022.6.24
随机推荐
力扣刷题日记/day3/2022.6.25
Torchdrug tutorial
使用FTP
Pb extended DLL development (super chapter) (VII)
2022健康展,北京健博会,中国健康展,大健康展11月13日
ByteDance dev better technology salon was successfully held, and we joined hands with Huatai to share our experience in improving the efficiency of web research and development
File processing examples of fopen, FREAD, fwrite, fseek
VMware Tools和open-vm-tools的安装与使用:解决虚拟机不全屏和无法传输文件的问题
[210] usage of PHP delimiter
Li Kou brush question diary /day6/6.28
Scala基础教程--13--函数进阶
Li Chi's work and life summary in June 2022
基于unity的愤怒的小鸟设计
vbs或vbe如何修改图标
基于C语言的菜鸟驿站管理系统
PB的扩展DLL开发(超级篇)(七)
Caché WebSocket
使用SSH
Scala basic tutorial -- 13 -- advanced function
基于NCF的多模块协同实例