• 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学习笔记 第四版》

  • 相关阅读:
    MySQL复制延时排查
    SQL优化之【类型转换】
    Twemproxy 介绍与使用
    Redis Cluster 3.0搭建与使用
    unauthenticated user reading from net
    XtraBackup之踩过的坑
    Redis学习之实现优先级消息队列
    如何保证接口的幂等性
    Redis缓存网页及数据行
    Rabbitmq 消费者的推模式与拉模式(go语言版本)
  • 原文地址:https://www.cnblogs.com/lanyangsh/p/9970602.html
Copyright © 2020-2023  润新知