Open cloudaice opened 9 years ago
channel
使用make
来初始化,也是Golang中为数不多的引用类型,也就是可以和nil
使用==
进行判断。
通常分为两种:
这两种channel的差别还是挺大的。在内存模型中,介绍到带buffer
的channel,写在读之前,而不带buffer
的channel
,读在写之前,也就是著名的happen before
原理中的一条。
创建一个不带buffer
的channel
的方法:
ch := make(chan int)
创建一个带buffer
的channel
的方法:
size := 10
ch := make(chan int, size)
如何判断一个buffer channel
是否被关闭?
要判断一个buffer channel
是否关闭,肯定是需要通过和channel
进行交互才可以完成,这里我实现了一个函数用于判断。
func isClosed(ch chan int) (ok bool) {
defer func() {
if r := recover(); r != nil {
ok = true
}
}()
select {
case ch <- 0:
default:
}
ok = false
return ok
}
因为一旦channel
被关闭了,那么写入必定是会引发panic
。实际上,当我们使用buffer channel
的时候,通常情况下我们是需要读取channel
里面的内容的。因此,我觉得还是通过下面的代码片段来判断比较好:
for {
v, ok := <-ch
if !ok {
// ch is closed
}
}
对空channel
的读操作会造成fatal error: all goroutines are asleep - deadlock!
对关闭的channel
的读操作则不会panic
你这个是因为读的时候,阻塞住了,使用select
加上default
就可以解决了。
或许,在有些时候,可以在关闭通道的时候,同时把通道赋值为nil.在使用该通道的时候,先做nil判断,然后再进行后续操作.
记录关于Golang中channel的一些机制和特性