Go channel原理分析

channel原理分析

数据结构

	type hchan struct {
		qcount   uint           		// 当前队列中剩余的元素个数
		dataqsiz uint           		// 环形队列的长度,即为缓冲区的大小
		buf      unsafe.Pointer 		// 指向环形队列的指针
		elemsize uint16					// 管道中元素的大小
		closed   uint32					// 管道是否关闭
		elemtype *_type 				// 元素的类型
		sendx    uint   				// 元素写入管道时存放到队列中的下标位置,队尾
		recvx    uint   				// 指定下一个从管道中读取元素在队列中的位置,队首
		recvq    waitq  				// 等待读消息的协程队列
		sendq    waitq  				// 等待写消息的协程队列
		lock mutex 						// 互斥锁,chan不允许并发读写
	}

从管道读数据时,如果缓冲区为空或者没有缓冲区,则当前协程会被阻塞,并加入recvq队列。
向管道写入数据时,如果缓冲区已满或者没有缓冲区,则当前协程会被阻塞,并加入sendq队列。

一般情况recvq和sendq至少有一个为空,除了同一个协程使用select向管道一边写数据,一边读数据,此时协程分别位于两个等待队列中。

协程读取管道时的阻塞条件:

  1. 管道无缓冲区
  2. 管道缓冲区无数据,协程会加入recvq队列
  3. 管道的值为nil

协程写入管道时的阻塞条件:

  1. 管道无缓冲区
  2. 管道缓冲区已满,协程会加入sendq队列
  3. 管道的值为nil

关闭管道需要注意的点:

  1. 唤醒recvq中的协程获取的数据都为nil
  2. 唤醒sendq中的协程并且触发panic
    以下操作会触发panic:
    关闭nil的管道
    关闭已经关闭的管道
    向关闭的管道写入数据

select的case在读管道时不会阻塞,读不到数据直接返回。
for-range读取管道中的数据时,当管道中没有数据则会阻塞。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
《Go语言底层原理剖析》这本电子书要深入探讨了Go语言的底层实现原理和机制。在Go语言快速发展的背后,了解其底层原理对于深入理解和优化代码至关重要。 首先,书中介绍了Go语言的内存管理。Go语言通过垃圾回收的方式自动管理内存,通过分代垃圾回收和并发标记等技术来提高垃圾回收的效率,并保证程序的性能。 其次,书中对Go语言的并发模型进行了详细解析。Go语言以轻量级的协程(goroutine)为基础,通过使用通道(channel)进行通信和同步,实现高效的并发编程。这本书从底层原理的角度深入剖析了协程的调度、通道的实现以及锁和同步原语等内容。 此外,书中对Go语言的编译器和运行时进行了解析。Go语言的编译器采用前端和后端分离的设计,通过词法分析、语法分析、类型检查和优化等步骤将Go源代码翻译成机器码。同时,Go语言的运行时系统提供了垃圾回收、调度器、内存管理等一系列功能,保证了程序的正确性和性能。 最后,本书还深入研究了Go语言的网络编程、文件IO、系统调用以及反射等底层机制。这些底层原理的理解,能够帮助开发者更好地理解和利用Go语言的特性,写出高效可靠的代码。 总之,《Go语言底层原理剖析》这本电子书通过深入剖析Go语言的底层原理,为读者提供了深入理解Go语言的机会,有助于开发者更好地应用Go语言进行编程,写出高性能、可靠的代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hewesH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值