1. 通道(channel)
通道是用来传递数据的一个数据结构。
通道遵循 先进先出的原则。
通道可用于两个goroutine 之间 通过 传递一个指定类型的值来同步运行和通信。
操作符 <- 用于指定通道的方向,发送或接收。
如果未指定方向,则为双向通道。
ch <- v // 把v 发送到通道ch
v := <- ch //从ch 接收数据,并把值赋给V
通道定义,
ch := make(chan int)
注意:默认情况下,通道是不带缓冲区的。发送端发送数据,同时必须有接收端接收相应的数据。
示例:
package main
import "fmt"
func main() {
s:= []int{1,2,3,4,5}
c := make(chan int)
go sum(s[:2],c)
go sum(s[2:],c)
x, y := <-c, <-c
fmt.Println(x/y)
}
func sum(s []int, c chan int) {
sum := 0
for _,v := range s {
sum += v
}
c <- sum
}
2. 通道缓冲区
通道可以设置缓冲区,通过make 的第二个参数指定缓冲区大小:
ch := make(chan int, 100)
带缓冲区的通道允许发送端的数据和接收端的数据处于异步状态,
即,发送端发送的数据可以放到缓冲区内,不用接收端立刻去接收。
注意:发送端端发送的数据 不能超过缓冲区大小。否则缓冲区一满就再也无法发送数据了。
如果通道不带缓冲区,发送方会阻塞直到接收方接收了值。
如果通道带缓冲,发送方则会阻塞直到发送的值被拷贝到缓冲区;
如果缓冲区已满,则需等待某个接收方接收值,接收前会一直阻塞。
package main
import "fmt"
func main() {
ch := make(chan int, 2)
ch <-1
ch <-2
fmt.Println(<-ch)
ch <-3
//ch <-4
fmt.Println(<-ch)
}
3. Go 遍历通道与关闭通道
Go 通过range 关键字来遍历通道,
判断通道内是否还有数据用 :
v, ok := <-ch
如果 接收不到数据,ok就为 false,
close函数用来关闭通道。
注意在使用range前 通道应处于关闭状态,否则将会死锁。
示例:
package main
import (
"fmt"
)
func main() {
ch := make(chan int, 2)
ch <-1
ch <-2
close(ch)
for aa := range ch {
fmt.Println(aa)
}
4. 通道权限控制
go func(c chan int) { //读写均可的channel c } (a) go func(c <- chan int) { //只读的Channel } (a) go func(c chan <- int) { //只写的Channel } (a)