golang channel幾點總結

golang提倡使用通信來共享數據,而不是經過共享數據來通信。channel就是golang這種方式的體現。golang

Channel

在golang中有兩種channel:帶緩存的和不帶緩存。緩存

  • 帶緩存的channel,也就是能夠異步收發的。
  • 不帶緩存的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

相關文章
相關標籤/搜索