Go 知识点(08) — 对未初始化的 channel 进行读写操作会造成永久阻塞,对其关闭会触发 panic

1. 对未初始化的 channel 进行写操作

先看下面代码

func main() {
	var ch chan int              // 只声明,并没有初始化
	fmt.Printf("ch is %v\n", ch) // ch is <nil>
	ch <- 1
}

运行上述代码,会有如下输出结果:

ch is <nil>
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send (nil chan)]:
main.main()
	/home/wohu/project/go/src/demo/demo.go:8 +0xa5
exit status 2

从打印结果我们可以看到,当仅仅声明一个 channel 但是并没有初始化时,对该通道进行写操作会一直阻塞 。

2. 对未初始化的 channel 进行读操作

先看下面代码

func main() {
	var ch chan int              // 只声明,并没有初始化
	fmt.Printf("ch is %v\n", ch) // ch is <nil>
	r := <-ch
	fmt.Printf("r is %v\n", r)
}

运行上述代码,会有如下输出结果:

ch is <nil>
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive (nil chan)]:
main.main()
	/home/wohu/project/go/src/demo/demo.go:8 +0xb9
exit status 2

同样结果会阻塞,此时报错信息是 chan receive (nil chan)

所以对于未初始化的通道进行读写操作时都会造成阻塞。

3. 对未初始化的 channel 进行关闭操作

那么对未初始化的 channel 进行关闭操作,会出现什么情况,看下面代码

func main() {
	var ch chan int              // 只声明,并没有初始化
	fmt.Printf("ch is %v\n", ch) // ch is <nil>
	close(ch)
}

输出结果为:

ch is <nil>
panic: close of nil channel

goroutine 1 [running]:
main.main()
	/home/wohu/project/go/src/demo/demo.go:10 +0x99
exit status 2

可以看到会有 panic 发生,所以在使用 channel 时一定要确保对其已经初始化操作。

Go 语言中的 Channel进行读、写、关闭等操作时有一些特殊的行为。下面我将分别介绍在 nil、关闭channel、有数据的 channel 进行读、写、关闭时的行为。 1. 对于 nil 的 channel 进行读写操作: 对于 nil 的 channel 进行读写操作导致 Goroutine 阻塞,并且在运行时抛出 panic 异常。因此,在使用 channel 时,一定要确保它不是 nil。 2. 对于关闭channel 进行读写操作: 如果一个 channel 已经被关闭,那么对它进行写操作导致 panic 异常。而对于读操作,如果 channel 中还有数据,那么可以正常读取并返回数据。但如果 channel 中已经没有数据了,那么读取操作返回一个零值,并且不阻塞。因此,在使用 channel 时,一定要注意判断 channel 是否已经被关闭。 3. 对于有数据的 channel 进行读写操作: 对于有数据的 channel 进行写操作阻塞当前 Goroutine,直到有其他 Goroutine 读取了数据。而对于读操作,如果 channel 中还有数据,那么可以正常读取并返回数据。但如果 channel 中已经没有数据了,那么读取操作阻塞当前 Goroutine,直到有其他 Goroutine 写入了数据或者 channel关闭。如果 channel关闭了,那么读取操作返回一个零值,并且不阻塞。 总之,当对 channel 进行读写操作时,需要注意它的状态,避免出现不必要的阻塞或异常。同时,对于已经关闭channel,不应该再进行写操作,否则导致 panic 异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wohu007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值