go channel 通道

介绍

channel 提供了一种通信机制,通过它,一个goroutine可以向另外一个goroutine发送消息。channel本身还需要关联一个类型,也就是channel可以发送数据的类型。

  1. goroutine,是传递消息的
  2. 每个都有相关的数据类型,nil chan 是不能使用的,类似于nil map,不能直接存储键值对
  3. 本身channel是同步的,意味着同一时间,只能有一条goroutine来操作
  4. 通道是goroutine之间的连接,所以通道的发送和接收必须处在不同的goroutine中
  5. 发送数据是阻塞的,直到另外一个goroutine读取数据来解除阻塞。读取数据也是阻塞的,直到另外一个goroutine来写入数据解除阻塞。
无缓冲的channel

从无缓存的 channel 中读取消息会阻塞,直到有 goroutine 向该 channel 中发送消息;同理,向无缓存的 channel 中发送消息也会阻塞,直到有 goroutine 从 channel 中读取消息。

有缓存的channel

有缓存的 channel 的声明方式为指定 make 函数的第二个参数,该参数为 channel 缓存的容量
ch := make(chan int ,10)
有缓存的 channel 类似一个阻塞队列(采用环形数组实现)。当缓存未满时,向 channel 中发送消息时不会阻塞,当缓存满时,发送操作将被阻塞,直到有其他 goroutine 从中读取消息;相应的,当 channel 中消息不为空时,读取消息不会出现阻塞,当 channel 为空时,读取操作会造成阻塞,直到有 goroutine 向 channel 中写入消息。
当缓存满了后,如果没有对应的goroutine读取数据,就会发生死锁

关闭channel
  1. 无论怎么都不应该在接收端关闭channel,因为在接收端无法判断发送端是否会向管道中发送元素值。
  2. 试图向已经关闭的channel发送数据会导致panic,从已关闭的channel 读取数据不会产生panic,且能读取channel中还未被读取的消息,若消息均已读出,则会读到类型的零值。从一个已关闭的 channel 中读取消息永远不会阻塞,并且会返回一个为 false 的 ok-idiom,可以用它来判断 channel 是否关闭
  3. 关闭已经关闭的channel会导致panic。
  4. 关闭一个未初始化nil的channel会产生panic。
  5. 关闭channel会产生一个广播机制,所有向channel读取消息的goroutine都会收到消息。
  6. 发送方结束后,一定要关闭channel,否则发生死锁,程序报错。
定向通道
  • 双向通道
  • 单向通道

创建双向通道,单向通道是作为函数参数的
ch := make(chan <- int) 单向,只能写,不能读
ch := make(<- chan int) 单向,只能读,不能写