1.简介
Channel(一般简写为 chan) 管道提供了一种机制:它在两个并发执行的协程之间进行同步,并通过传递与该管道元素类型相符的值来进行通信,它是Golang在语言层面提供的goroutine间的通信方式.通过Channel在不同的 goroutine中交换数据,在goroutine之间发送和接收消息,并且可以通过Channel实现Go依赖的CSP的并发模型这种同步模式
chan 可以理解为一个管道或者先进先出的队列,Golang并发的核心哲学是:不要通过共享内存来通信,而应该通过通信来共享内存,所以数据在不同协程中的传输都是通过拷贝的形式完成的,并且 channel 本身还可以支持有缓冲和无缓冲的,通过 channel + timeout 实现并发协程之间的同步也是常见的一种使用姿势
2.channel结构体
简单说明:
buf是有缓冲的channel所特有的结构,用来存储缓存数据,是个循环链表sendx和recvx用于记录buf这个循环链表中的发送或者接收的indexlock是个互斥锁recvq和sendq分别是接收(<-channel)或者发送(channel <- xxx)的goroutine抽象出来的结构体(sudog)的队列,是个双向链表
type hchan struct {
qcount uint // total data in the queue 当前队列里还剩余元素个数
dataqsiz uint // size of the circular queue 环形队列长度,即缓冲区的大小,即make(chan T,N) 中的N
buf unsafe.Pointer // points to an array of dataqsiz elements 环形队列指针
elemsize uint16 //每个元素的大小
closed uint32 //标识当前通道是否处于关闭状态,创建通道后,该字段设置0,即打开通道;通道调用close将其设置为1,通道关闭
elemtype *_type // element type 元素类型,用于数据传递过程中的赋值
sendx uint // send index 环形缓冲区的状态字段,它只是缓冲区的当前索引-支持数组,它可以从中发送数据
recvx uint // receive index 环形缓冲区的状态字段,它只是缓冲区当前索引-支持数组,它可以从中接受数据
recvq waitq // list of recv waiters 等待读消息的goroutine队列
sendq waitq // list of send waiters 等待写消息的goroutine队列
// lock protects all fields in hchan, as well as several
// fields in sudogs blocked on this channel.
//
// Do not change another G's status while holding this lock
// (in particular, do not ready a G), as this can deadlock
// with stack shrinking.
lock mutex //互斥锁,为每个读写操作锁定通道,因为发送和接受必须是互斥操作
}
// sudog 代表goroutine
type waitq struct {
first *sudog
last *sudog
}

3.Channel 操作符和操作方式
通信操作符
<-的箭头指示数据流向,箭头指向哪里,数据就流向哪里,它是一个二元操作符,可以支持任意类型,对于 channel 的操作只有4种方式:
- 创建 channel (通过make()函数实现,包括无缓存 channel 和有缓存 channel);
- 向 channel 中添加数据(channel<-data);
- 从

最低0.47元/天 解锁文章
1926

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



