我们先看下面代码输出通道的长度是多少?

func main() {ch := make(chan string)go func() {ch <- "hello"close(ch)}()time.Sleep(5 * time.Second)fmt.Println("ch length is ", len(ch))<-ch
}

是 1 吗? 答案是: 0, 为什么呢?

我们来分析下,首先在主协程中创建了一个通道,然后在子协程中往这个通道中发送内容,发送完毕后关闭通道,然后在主协程中等待 5s, 等待的目的是让子协程能够运行起来,随后我们打印通道的长度。

我们知道对于非缓冲通道而言,发送方和接收方必须同时准备好,这样数据才能发送过去,而在上面代码中我们先打印通道的长度,然后主协程作为接收方才会从通道中取消息内容,所以我们打印通道的时候由于接收方还没有准备接收,从而导致发送方一直处于阻塞状态,此时消息是没有进入到通道的,所以此时的通道长度为 0 。

非缓冲通道并不需要内存空间来存储发送的消息内容,它在发送方和接受方都准备好时,直接将发送方的消息内容拷贝到接收方。

缓冲通道在容量够的时候,写入操作并不会阻塞,是否阻塞强依赖于读取操作,发送方发送数据后直接返回,这样就决定了缓冲通道需要一块存储空间来真正存储要发送的消息内容。

在多核 CPU 下的 Go 多协程环境,必然会出现多个协程同时并行的对同一个 channel 进行读取操作的情况,这样就带来了资源并发访问的问题。

对于非缓冲通道,发送方与接收方必须是一对一、点对点的操作。如果有多个协程同时对某一个非缓冲 channel 进行操作,那么就会发生有部分读/写操作不能匹配到相应的写/读操作,必然会导致死锁。

对于缓冲通道,由于 Go 采用对通道接收的锁机制,即在接收方在取通道内容时,先用锁把通道锁住,然后取数据,取完数据之后再释放锁,这样就保证了多个协程之间是顺序执行的,不会发生多个协程获取通道里的同一个数据的问题,在某一个协程进行接收操作的时候,其他协程只能阻塞在那里,等待上一个协程释放锁,这样就保证了通道数据的并发安全性。

同样发送方也遵循这样的锁机制,即保证同一时刻只有一个协程来操作通道。

Go 知识点(03)— 非缓冲 channel 的长度始终为 0相关推荐

  1. 【C 语言】文件操作 ( 文件加密解密 | 加密解密原理 | 对称加密原理 | 非密钥整数倍长度的数据加密处理 )

    文章目录 一.对称加密原理 二.非密钥整数倍长度的数据加密处理 一.对称加密原理 给定一个 密钥 , 密钥的 长度不确定 , 可能是 323232 字节 , 也可能是 646464 字节 ; 将 被加 ...

  2. 无缓冲channel

    ch := make(chan int) 无缓冲的channel由于没有缓冲发送和接收需要同步. ch := make(chan int, 2) 有缓冲channel不要求发送和接收操作同步. cha ...

  3. php mysql 非扫描,PHP的中使用非缓冲模式查询数据库的方法

    最近在开发一个PHP程序时遇到了下面的错误: PHP Fatal error: Allowed memory size of 268 435 456 bytes exhausted 错误信息显示允许的 ...

  4. C语言不用文件系统读取文件,C语言-基础教程-非缓冲文件系统

    前面介绍的缓冲文件系统是借助文件结构体指针来对文件进行管理,通过文件指针来对文件进行访问,既可以读写字符.字符串.格式化数据,也可以读写二进制数据.非缓冲文件系统依赖于操作系统,通过操作系统的功能对文 ...

  5. 无缓冲channel的内存泄漏问题

    无缓冲channel的内存泄漏问题:无缓冲channel在go程里done <- hardWork(job)时,如果外层执行完了后,done <- hardWork(job)写操作< ...

  6. 缓冲文件系统(fopen/fread/fwrite)和非缓冲文件系统(open/read/write)

    open:系统调用,返回的是文件描述符,即文件句柄,是文件在文件描述副表里的索引. fopen:C语言库函数,返回的是一个指向文件结构的指针.fopen是ANSI C标准中的C语言库函数,在不同的操作 ...

  7. C语言缓冲文件系统和非缓冲文件系统

    C 语言所使用的磁盘文件系统有两大类:一类称为缓冲文件系统,又称为标准文件系统:另一类称为非缓冲文件系统. 缓冲文件系统的特点是系统自动地在内存区为每一个正在使用的文件开辟一个缓冲区.从磁盘向内存读入 ...

  8. 无缓冲channel与容量为1的channel的区别

    有缓冲和无缓冲channel的声明 下面简要说明它们之间的区别,先声明两个channel分别有缓冲1和无缓冲: 复制代码 c1 := make(chan int) // 无缓冲 c2 := make( ...

  9. Java-Runoob-高级教程-实例-数组:03. Java 实例 – 获取数组长度-*

    ylbtech-Java-Runoob-高级教程-实例-数组:03. Java 实例 – 获取数组长度 1.返回顶部 Java 实例 - 获取数组长度  Java 实例 本文我们将为大家介绍如何使用数 ...

最新文章

  1. 基于Go的语义解析开源库FMR,“屠榜”模型外的NLP利器
  2. python基本用法_python基本用法
  3. 11组软件工程组队项目失物招领系统——进度汇报和下周目标
  4. 敏捷开发框架_他山之石-敏捷开发管理框架在设计项目中的应用
  5. 32.Docker安装MongoDb
  6. php发送post请求方法
  7. 一文快速了解oCPX
  8. asn1 pem pfx格式证书_Linux使用openssl管理自签名证书保障网络安全
  9. 深入浅出Node.js(一):什么是Node.js
  10. 如何在Mac上使用触控栏?
  11. apache的es的原理_Elasticsearch Lucene 数据写入原理 | ES 核心篇
  12. 移动应用android简单播放器,打造移动掌上影院 Android播放器横评
  13. 修改手机定位 之 Fake Location 软件使用教程
  14. 做华为外包一年的总结
  15. js 实现大小写转换的方法
  16. Android基础整合项目之节日群发助手(三)
  17. GYM 101173 K.Key Knocking(构造)
  18. C++中cout<<后面加endl什么意思?
  19. spark:报错com.esotericsoftware.kryo.KryoException: Buffer underflow.
  20. javascript正则迷你书-笔记

热门文章

  1. 2022-2028年中国环卫行业产业链深度调研及投资前景预测报告
  2. 2022-2028年中国炼钢行业市场研究及前瞻分析报告
  3. C++ 笔记(31)— 类继承
  4. Python 多线程总结(1)- thread 模块
  5. 利用exchangelib快速上手使用python发邮件
  6. 语义网所谓的“本体”的具体例子是什么?人工智能
  7. LeetCode简单题之仅执行一次字符串交换能否使两个字符串相等
  8. 深度学习数据集定义与加载
  9. AI+IoT+电池应用
  10. Nucleus 实时操作系统中断(上)