GolangEP02_并发中的Channel

前言 让我们看看关于 chan 有哪些常见的操作。 创建channel ch1 := make(chan int) ch2 := make(chan int, 2) 底层实际上调用的是makechan方法 发送数据到channel ch <- 1 底层实际调用的是chansend1,而chansend1最终也是调用chansend,将block参数设置为true——当前发送操作是阻塞的 从channel中读取数据 i <- ch i, ok <- ch 底层实际调用的是chanrecv1和chanrecv2,最终都去调用了chanrecv。 源码 接下来我们进入源码中一探究竟。 hchan结构体 type hchan struct { qcount uint // total data in the queue dataqsiz uint // size of the circular queue buf unsafe.Pointer // points to an array of dataqsiz elements elemsize uint16 synctest bool // true if created in a synctest bubble closed uint32 timer *timer // timer feeding this chan elemtype *_type // element type sendx uint // send index recvx uint // receive index recvq waitq // list of recv waiters sendq waitq // list of send waiters // 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 } qcount:通道中存储的数据元素总数 dataqsiz:环形队列大小 buf:执行环形队列的内存缓冲区,存放实际数据——环形缓存区域,本质上是一个带有头尾指针的固定长度的数组 sendx,recvx:发收操作的队列位置 recvq,sendq:等待队列 可以发现,hchan 使用环形队列表示缓冲区并且采用 lock 确保并发访问的安全性。 ...

十二月 5, 2024 · 8 分钟 · LTX
0:00 --:--