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

相关文章
相关标签/搜索