go channel 的设计原理

本文探讨了Go语言中gochan的设计原理,强调了其不采用传统通信方式,而是通过通信共享内存的思想。介绍了chan的数据结构,如缓冲区大小、环形队列、元素类型和同步机制,以及无锁Channel的实现挑战。
摘要由CSDN通过智能技术生成

如果我是面试官,让你说说go chan的设计原理你会怎么说呢?

我理解go在协程的通信中是花了大心思的,他并没有走相对老套的通信方式(无名管道,有名管道,共享内存,套接字,信号量),而是提出了新的思想,不要通过共享内存的方式进行通信,而是应该通过通信的方式共享内存,这句话很拗口,我并不想强调它。记住他这个CSP<(通信顺序进程(Communicating sequential processes)>新思想即可。

协程主要的数据结构有哪些?

  1. 最基础的,chan分为有缓冲和无缓冲你知道的吧。既然有缓冲,肯定得有个字段来记录你申请的这个chan 的cap是多大吧,他不可能无限大。所以应该有个容量的记录字段吧**dataqsiz **
  2. 他肯定有个字段来记录目前chan里面有多少个元素了qcount
  3. 我们是不是应该考虑资源的重复利用?重复使用可以减少系统调用,这里chan使用的是环形队列 ****
  4. 既然有了环形队列自然而然的就应该想到有两个指针,表示消息当前生产者写到哪个位置了sendx,消费者读到哪个位置了recvx
  5. 申请chan的时候你还记得必须有消息类型吗?是的,同样还得有个字段记录消息类型**elemtype **
  6. chan 是一个线程安全的通信媒介怎么可能没有锁呢?lock 之前我说到有锁这个事情的时候他笑话我说,呵呵,chan其实是没有锁的 目前通过 CAS 实现的无锁 Channel 没有提供先进先出的特性,所以该提案暂时也被搁浅了,所以chan是有锁的实现,请参考Dmitry Vyukov. Dec, 2016. “algorithm does not apply per se

chan的基本框架已经出来了,能说到这里基本上差不多了吧,接下来我们看下源码的定义

go chan struct

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
}

type waitq struct {
	first *sudog
	last  *sudog
}

提纲挈领的说一些自己思考chan的思路,更有助于记住这些原理

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值