Go语言的并发模型是CSP(Communicating Sequential Processes),提倡通过通信共享内存而不是通过共享内存而实现通信
channel是Go程序并发线程之间的连接,channel是可以让一个goroutine发送特定值到另外一个goroutine的通信机制
channel是一个FIFO的管道,保证收发数据的顺序。每一个通道都是一个具体类型的导管,也就是声明channel的时候需要为其指定元素类型。
通道是引用类型,通道类型的空值是nil
var ch chan int
声明后需要使用make函数初始化之后才能使用
make(chan int)
channel操作:
send ,receive ,close
接收和发送都是要 <- 符号
ch := make(chan int)
ch <- 10
x := <- ch
<- ch //从ch中接收值,忽略结果
close(ch)
只有在通知接收方goroutine所有的数据都发送完毕的时候才需要关闭通道。
通道是可以被垃圾回收机制回收的,它和关闭文件是不一样的,在结束操作之后关闭文件是必须要做的,但关闭通道不是必须的。
关闭后的通道有以下个点:
对一个关闭的通道再发生值就会导致panic
对一个关闭的通道进行接收会一直获取值直到通道为空
对一个关闭的并且没有值的通道执行接收操作会得到对应类型的零值
关闭一个已关闭的通道会导致panic
无缓冲通道:又称阻塞的通道(同步通道)
make(chan int) //无缓冲区
make(chan int , 1) //有缓冲区,缓冲区大小为1
len(ch1)
cap(ch1)
声明管道的时候使用<-放在 chan两边可以限定单向通道
ch chan<- int //只写通道
ch <-chan int //只读通道
worker pool (goroutine池)
工作中我们通常会使用workerpool模式,控制goroutine数量,防止goroutine泄漏和暴涨
select多路复用
在某些场景下我们需要同时从多个通道接收数据,通道再接收数据时,如果没有数据可以接收将会发生阻塞。
select的使用类似于switch语句,他有一些列case分支和一个默认的分支。每个case会对应一个通道的通信(接收或发送)过程。select会一直等待,直到某个case的通信操作完成时,就会执行case分支对应的语句。
可处理一个或多个channel的发送、接收操作
如果多个case同时满足,select会随机选择一个
如果没有case的select{}会一直等待,可用于阻塞main函数