golang提倡使用通信来共享数据,而不是经过共享数据来通信。channel就是golang这种方式的体现。golang
在golang中有两种channel:带缓存的和不带缓存。缓存
• 向 nil channel 发送数据,阻塞。
• 向 closed channel 发送数据,出错。
• 同步发送: 若有接收者,交换数据。不然排队、阻塞。
• 异步发送: 若有空槽,拷⻉贝数据到缓冲区。不然排队、阻塞。并发
• 从 nil channel 接收数据,阻塞。
• 从 closed channel 接收数据,返回已有数据或零值。
• 同步接收: 若有发送者,交换数据。不然排队、阻塞。
• 异步接收: 若有缓冲项,拷⻉贝数据。不然排队、阻塞。异步
使用channel时,多个goroutine并发发送和接收,却无需加锁,为何呢?学习
其实,是由底channel层实现作支撑的。ui
channel的具体定义参见/usr/local/go/src/runtime/chan.gothis
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 closed uint32 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 }
能够看到,有lock字段,在使用channel进行发送和接收的时候,会进行加锁保护。code
雨痕《Go学习笔记 第四版》ci