持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
golang之channels
前文
本文内容为关于golang中channels的一些知识的整理和总结。其中内容可能不够完整或不够准确,主要是作为一个学习知识内容的整理。
golang的channels
要讨论golang的channels,首先我们要了解一下什么是channels。channels可以认为是golang中的一种通信管道。而channel本身又是协程的一种通信方式。通过channel,可以进行协程间的通信。
和map的方式类似,channel其实是一个对于底层数据的引用。当我们进行channel的复制或传递时,其实底层的数据是相同的,并不是两个不同的对象。如果两个channel底层的对象是一致的,那么我们就可以认为二者是相等的,也就是用等号会判断为true。
channel包含数据发送和数据接收两种操作。数据发送及接收分别是通过两个方向的箭头进行表示:
ch <- x // 像channel发送数据
x = <-ch // 从channel接收数据
<-ch // channel移除数据,但没有接收对象
channel支持close操作。当关闭后,不能向channel发送数据,但是依然可以读取channel输出的数据。
如果channel的容量是0,则是无缓存的channel;如果channel容量大于0,则是有缓存的channel。
不带缓存的channel
不带缓存的channel的发送操作会导致goroutine阻塞,直到channel中的数据被其他goroutine接收。
func main() {
conn, err := net.Dial("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
done := make(chan struct{})
go func() {
io.Copy(os.Stdout, conn)
log.Println("done")
done <- struct{}{}
}()
conn.Close()
<-done
}
带缓存的channel
ch = make(chan string, 3)
带缓存的channel如果缓存已经全部插入元素,则该goroutine进入阻塞状态,而在获取时如果元素已经为空同样进入阻塞状态。采用caps查看channel的容量,使用len查看channel中有效元素的个数。如果没达到缓存的数量,也就不会发生阻塞的问题。
后记
- 千古兴亡多少事?悠悠。不尽长江滚滚流。