1. 通道是什么?Go并发的沟通艺术
在Go语言的世界里,goroutine是轻量级线程,让并发编程变得简单。但单纯地将函数并发执行是没有意义的,函数与函数之间需要交换数据才能体现并发执行的价值。
那么,goroutine之间如何交流呢?就像人类需要语言,goroutine也需要自己的沟通方式——这就是channel(通道)。
Go语言的并发哲学是:"不要通过共享内存来通信,而应该通过通信来共享内存"。通道正是这一哲学的实践,它允许不同的goroutine之间进行安全的数据交换,避免了传统共享内存方式带来的竞态问题。
想象一下通道就像goroutine之间的快递系统:有的像快递员当面交接(无缓冲通道),有的像快递柜暂时存放(有缓冲通道)。接下来,我们将深入探索通道的基本操作,让你彻底掌握goroutine的沟通艺术!
2. 通道基础:创建、发送、接收和关闭
2.1 创建通道:给goroutine搭桥
通道是一种引用类型,使用前必须初始化。就像你需要先准备快递包装才能寄送物品一样。
var ch1 chan int // 声明一个传递整型的通道,此时ch1是nil
var ch2 chan bool // 声明一个传递布尔型的通道
var ch3 chan []int // 声明一个传递int切片的通道
// 通道需要用make函数初始化才能使用
ch4 := make(chan int) // 无缓冲通道
ch5 := make(chan bool, 1) // 有缓冲通道,容量为1
ch6 := make(chan []int, 3) // 有缓冲通道,容量为3
声明通道的通用格式是var 变量 chan 元素类型。每个通道都有相关联的数据类型,只能传递该类型的值。
2.2 发送与接收:goroutine的对话
通道使用<-符号进行数据的发送和接收,这个箭头表示数据的流动方向。
ch := make(chan int)
// 发送操作:将值发送到通道中
ch <- 10 // 把10发送到通道ch
// 接收操作:从通道中接收值
x := <-ch // 从ch中接收值并赋值给变量x
<-ch // 从ch中接收值,但忽略结果
发送和接收操作默认是阻塞的,这是通道最重要的特性之一:
- 发送操作会阻塞,直到有另一个goroutine准备接收该值
- 接收操作会阻塞,直到有另一个goroutine发送值到通道
2.3 关闭通道:礼貌地结束对话
当通道不再需要时,应该关闭它,但这并非强制要求。
ch := make(chan int)
close(ch) // 关闭通道
关闭通道需要注意:
- 只有在通知接收方所有数据都发送完成时才需要关闭通道
- 通道可以被垃圾回收机制回收,与文件不同,关闭通道不是必须的
- 关闭一个已经关闭的通道会导致panic
- 对一个关闭的通道发送值也会导致panic

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



