22 数据通道(channel)和多路选择(select)
通道是给定数据类型的值的线程安全的队列。
通道的最重要应用就是协程之间的通信。
因此,我们说把值发送到通道(ch <- value
)和从通道中接收值(value <- ch
)。
通道的基本用法:
通道的零值是nil
。向nil
通道中发送数据将会永远阻塞(译者注:程序会异常退出),所以第一件事情就是用make(chan <type>, <queue size>)
创建通道。队列大小是可选参数,缺省时创建的就是无缓冲通道(unbuffered channel),你可以认为队列大小为0。
译者注
注意chInts := make(chan int)
和 chInts := new(chan int)
的区别。除了前者返回变量值后者返回变量指针之外,前者返回的是队列大小为0的无缓冲通道,后者指向的是零值nil
。
发送操作符chan <- value
会把值放到队列的尾部。
如果队列满了,则发送操作<-
会阻塞。
若向nil
通道发送,则会永远阻塞。
接收语句value = <- chan
则是从队列头部获取值。
如果队列空了,则接收操作会阻塞。
另一个从通道中获取数据的方法是使用select
语句。
使用select
则允许:
在多个通道上等待
实现非阻塞等待
通过等待一个计时器通道来实现超时
还有另一种获取方法是使用range
语句。
通道具有固定大小的容量。
创建通道时若不显式指定队列大小(例如make(chan int)
),则队列大小为0,又称为无缓冲通道。向无缓冲通道发送数据会一直阻塞,直到相应的接收操作完成。
创建通道时若显式指定了队列大小(例如make(chan int, 3)
),则被称为容量为3的有缓冲通道。前3次发送数据会立即完成,而第4次则会一直阻塞,直到队列中有值被拿走腾出空间。
您可以使用close(chan)
语句关闭通道。
已关闭的通道再次关闭则会发生恐慌。
向已关闭的通道发送数据也会发生恐慌。
从已关闭的通道接收数据则会:
返回已缓冲的数据
若已缓冲数据已被取完,则会立即返回零值
关闭通道同样会使正在迭代访问通道的range
操作终止。
最后更新于