1. 程式人生 > >golang channel幾點總結

golang channel幾點總結

golang提倡使用通訊來共享資料,而不是通過共享資料來通訊。channel就是golang這種方式的體現。

Channel

在golang中有兩種channel:帶快取的和不帶快取。

  • 帶快取的channel,也就是可以非同步收發的。
  • 不帶快取的channel,也就是同步收發的。

傳送:

• 向 nil channel 傳送資料,阻塞。
• 向 closed channel 傳送資料,出錯。
• 同步傳送: 如有接收者,交換資料。否則排隊、阻塞。
• 非同步傳送: 如有空槽,拷⻉貝資料到緩衝區。否則排隊、阻塞。

接收:

• 從 nil channel 接收資料,阻塞。
• 從 closed channel 接收資料,返回已有資料或零值。
• 同步接收: 如有傳送者,交換資料。否則排隊、阻塞。
• 非同步接收: 如有緩衝項,拷⻉貝資料。否則排隊、阻塞。

底層實現

使用channel時,多個goroutine併發傳送和接收,卻無需加鎖,為什麼呢?

其實,是由底channel層實現做支撐的。

channel的具體定義參見/usr/local/go/src/runtime/chan.go

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進行傳送和接收的時候,會進行加鎖保護。

參考

雨痕《Go學習筆記 第四版》