Go中channel机制介绍

171 阅读1分钟

语法

在Go中,channel结构是Goroutine间消息传递的基础,属于基本类型,在runtime库中以C语言实现。 Go中针对channel的操作主要包括以下几种:

  • 创建:ch = make(chan int, N)
  • 发送:ch <- l
  • 接收:l <- ch
  • 关闭:close(ch)

另外,还可以通过select语句同时在多个channel上进行收发操作,语法如下:

select {
case ch01 <- x:
... ... /* do something ... */
case y <- ch02:
... ... /* do something ... */
default:
... ... /* no event ... */
}

此外,基于select的操作tai还支持超时控制,具体的语法示例如下:

select {
case v := <- ch:
... ...
case <- time.After(5 * time.Second):
... ...
}

尽管Go以消息传递作为Goroutine间交互的主要方式,但是基于channel的通信又必须依赖channel引用的共享才能得以实现, 因此Go语言绝不是一种纯粹的消息传递语言。 一般而言,channel的引用可以通过以下几种方式在不同Goroutine间共享:

“父Goroutine” 的栈变量,通过用Go语句创建Goroutine时的参数进行传递

ch = make (chan int)
go fn (ch)
l <- ch

“父Goroutine” 的栈变量,Go创建的Goroutine以闭包作为执行函数,栈变量自动共享

ch = make (chan int)
go func () { i = 1; chan <- i; } ()
x <- chan

由于Go的垃圾收集器认为channel的引用只能在栈上,因此一般不用全局的引用进行共享

另外,在创建channel时,还可以指定是否采用buffer及buffer的大小,默认buffer为0 。 当buffer大于0时,可以进行异步的消息传递:接收方只有在当前buffer为空时才阻塞,而发送方则只有在buffer满时才阻塞。