cloudaice / learnGo

there are something about Go Useage
MIT License
0 stars 0 forks source link

关于channel的特性 #9

Open cloudaice opened 9 years ago

cloudaice commented 9 years ago

记录关于Golang中channel的一些机制和特性

cloudaice commented 9 years ago

channel使用make来初始化,也是Golang中为数不多的引用类型,也就是可以和nil使用==进行判断。

通常分为两种:

这两种channel的差别还是挺大的。在内存模型中,介绍到带buffer的channel,写在读之前,而不带bufferchannel,读在写之前,也就是著名的happen before原理中的一条。

创建一个不带bufferchannel的方法:

ch := make(chan int)

创建一个带bufferchannel的方法:

size := 10    
ch := make(chan int, size)
iSpoony commented 9 years ago

如何判断一个buffer channel是否被关闭?

cloudaice commented 9 years ago

要判断一个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
    }
}
iSpoony commented 9 years ago

对空channel的读操作会造成fatal error: all goroutines are asleep - deadlock! 对关闭的channel的读操作则不会panic

cloudaice commented 9 years ago

你这个是因为读的时候,阻塞住了,使用select加上default就可以解决了。

cloudaice commented 9 years ago

或许,在有些时候,可以在关闭通道的时候,同时把通道赋值为nil.在使用该通道的时候,先做nil判断,然后再进行后续操作.