zoukankan      html  css  js  c++  java
  • 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学习笔记 第四版》

  • 相关阅读:
    平台架构设计及市场分析
    编写jQuery插件
    分布式锁
    初探12306售票算法(一)- 理论(转)
    年后跳槽如何准备?(转)
    therefore/so/hence/then/accordingly/Thus
    ignore,neglect,omit,overlook
    OOA/OOD/OOP(转)
    SQL Server里的 ISNULL 与 NULLIF
    稀疏矩阵
  • 原文地址:https://www.cnblogs.com/lanyangsh/p/9970602.html
Copyright © 2011-2022 走看看