如果说 goroutine 是 Go语言程序的并发体的话,那么 channels 就是它们之间的通信机制。一个 channels 是一个通信机制
- 不需要的时候关闭通道close(ch)
- 可以通过range遍历通道内容
- 双向通道能隐式转换为单项通道,单项通道不能隐式转换为双向通道
- 关闭通道
close(ch) - 写入数据
ch <- VALUE //向ch这个channel写入数据 - 读取数据
<-ch // 从ch中读取一个值 接收并且将其丢弃
val := <-ch // 从ch中读取一个值并保存到val变量中
val,ok = <-ch // 从ch读取一个值,判断是否读取成功,如果成功则保存到val变量中
无缓冲区的通道
c := make(chan int)
- 如果通道不带缓冲,发送方会
阻塞
直到接收方从通道中接收了值。如果通道带缓冲,发送方则会阻塞直到发送的值被拷贝到缓冲区内;如果缓冲区已满,则意味着需要等待直到某个接收方获取到一个值。接收方在有值可以接收之前会一直阻塞。 - 通道接收和发送都是阻塞的,除非另一方已经准备好,这样就使得Goroutine同步更简单,而不需要显示加锁
有缓冲区的通道
ch := make(chan int, 100)
带缓冲区的通道允许发送端的数据发送和接收端的数据获取处于异步状态,就是说发送端发送的数据可以放在缓冲区里面,可以等待接收端去获取数据,而不是立刻需要接收端去获取数据。
不过由于缓冲区的大小是有限的,所以还是必须有接收端来接收数据的,否则缓冲区一满,数据发送端就无法再发送数据了。
单向通道
// 声明一个只能写入数据的通道类型, 并赋值为ch
var chSendOnly chan<- int = ch
//声明一个只能读取数据的通道类型, 并赋值为ch
var chRecvOnly <-chan int = ch
chan T // 可以接收和发送类型为 T 的数据
chan<- float64 // 只可以用来发送 float64 类型的数据
<-chan int // 只可以用来接收 int 类型的数据