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