概述
Channel 是Golang 在语言级别提供的goroutine 之间的通信方式。
注意:Channel 是进程内的通信方式,因此通过 channel 传递对象的过程和调用函数时的参数传递行为比较一致,比如也可以传递指针等。使用通道发送和接收所需的共享资源,可以在 goroutine 之间消除竞争条件。一个channel 只能传递一个类型的值,这个类型需要在声明channel的时候指定。
设计原理
设计模式:不要通过共享内存的方式进行通信,而是应该通过通信的方式共享内存。
在Go语言中提供通信顺序进程(Communicating sequential processes,CSP)
CSP并发模型是上个世纪七十年代提出来的,用于描述两个独立的并发实体通过共享内存通讯进行通讯的并发模型。在Golang中并没有完全实现CSP模型的所有理论,仅仅借用process和channel这两个概念。在golang 中process(goroutine实际执行并发的实体),实体间通过channel实现共享数据。
数据结构
type hchan struct {// chan 里元素数量qcount uint// chan 底层循环数组的长度dataqsiz uint// 指向底层循环数组的指针// 只针对有缓冲的 channelbuf unsafe.Pointer// chan 中元素大小elemsize uint16// chan 是否被关闭的标志closed uint32// chan 中元素类型elemtype *_type // element type// 已发送元素在循环数组中的索引sendx uint // send index// 已接收元素在循环数组中的索引recvx uint // receive index// 等待接收的 goroutine 队列recvq waitq // list of recv waiters// 等待发送的 goroutine 队列sendq waitq // list of send waiters// 保护 hchan 中所有字段lock mutex}
创建channel
// 创建带缓存的channelch := make(chan int, 10)// 创建不带缓存的channelch := make(chan int)
发送数据
// 发送数据ch <- i
发送数据是怎样的一个过程
https://golang.design/go-questions/channel/send/
接收数据
// 接收数据i <- chi,ok <- ch
关闭channel
// 关闭 channelclose ch
