// 源码来自Go 1.19 // 源码包:src/runtime/chan.go type hchan struct { qcount uint// 当前队列中剩余的元素个数 dataqsiz uint// 环形队列长度、即可以存放的元素个数 buf unsafe.Pointer // 环形队列指针 elemsize uint16// 每个元素的大小 closed uint32// 关闭标示字段 elemtype *_type // 元素类型 sendx uint// 队列下标、元素写入时存放在队列中的位置 recvx uint// 队列下标、指示下一个被读取的元素在队列中的位置 recvq waitq // 等待读消息的协程队列 sendq waitq // 等待写消息的协程队列 // 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 // 互斥锁、保证chan并发安全操作 }
funcmain() { var ch1 = make(chanint, 10) var ch2 = make(chanint, 10) go work(ch1) go work(ch2) for{ select{ case e:=<-ch1: fmt.Printf("get element from ch1:%d\n", e) case e:=<-ch2: fmt.Printf("get element from ch2:%d\n", e) default: fmt.Println("no element in ch1 and ch2!") time.Sleep(time.Second * 1) } } }