环球资讯:[Golang]Go的channel

来源:腾讯云

2023-03-15 14:12:19

概论

Go语言官网中,是这么定义Channel这个类型的。


(资料图片)

A channel provides a mechanism for [concurrently executing functions] (golang.google.cn/ref/spec#Go…) to communicate by sending and receiving values of a specified element type. The value of an uninitialized channel is nil. 通道为并发执行函数提供了一种机制,通过发送和接收指定元素类型的值来进行通信。 未初始化通道的值为 nil。

“不要通过共享内存的方式进行通信,而是应该通过通信的方式共享内存。” 这句话体现了Go语言对于并发设计的理念,channel也是实现CSP理论的重要一员。

基本操作

言归正传,下面我们具体聊聊Channel

对于我来说,通道分两种:

无缓冲:无缓冲的在并发编程中,体现在同步。有缓存:有缓冲则体现在异步。

有无缓冲的通道的创建相差不多,只是参数的差异

Talk is cheap, show me the code —— Linux创始人Linus

下面我们通过一段简单的代码,来描述通道的创建和操作。

//同步通道     ch1 := make(chan int)     //异步通道, 缓冲区大小为1     ch2 := make(chan int, 1) ​     //写数据     ch2 <- 1     //取数据     <- ch2     //关闭一个channel     close(ch2)复制代码

把上面我们创建通道,其中包括int指定通道中可以放如的类型。

要理解通道,我们可以先把他当作一个FIFO的队列。

我们可以把ch2类比成一个可以放一个元素的队列。

那么ch1呢? 是能放0个元素的通道? 是的,没错!那么怎么通过ch1进行协程间通讯呢?

还记得我们在最上面说过,Channel分两种, 有一种是同步的吗?也就是说,两个协程,要通过 ch1做通讯,他们必须"握手"。一个协程往ch1中放数据的时候,必须阻塞等待有另外一个携程过来取,发生握手交换数据。

协程对channel的读写流程:

发送方向缓冲区写入数据,会唤醒等待接受的接收方,多个接收方会尝试从缓冲区中读取数据,如果没有读取到会重新陷入休眠;接收方从缓冲区中读取数据,会唤醒等待写入发送方,发送方会尝试向缓冲区写入数据,如果缓冲区已满会重新陷入休眠;

遇到过的坑

已经关闭的chan不能写,可以读对于channel的遍历最好使用range

源码

Channel的操作比较简单,下面我们通过Go的源码,看看的内部是如何实现的。chan的结构体定义在${GOROOT}/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 } ​复制代码
qcount— Channel 中的元素个数;dataqsiz— Channel 中的循环队列的长度;buf— Channel 的缓冲区数据指针;sendx— Channel 的发送操作处理到的位置;recvx— Channel 的接收操作处理到的位置;

通过上面的结构体,我么可以抽象出下面一幅图:

小结

channel是并发控制中的新成员,虽然他内部也有锁,但是对于我们来说他是无感的,在官方网络库中,Go使用很多通道来做并发控制。

作者:OpenStack链接:https://juejin.cn/post/7010772020459733005来源:稀土掘金著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

关键词:

环球资讯:[Golang]Go的channel

“不要通过共享内存的方式进行通信,而是应该通过通信的方式共享内存。”这句话体现了Go语言对于并发设计的理念,channel也是实现CSP理论的重[详细]
2023-03-15

美媒称“中国遭虫雨袭击”,中国网友看笑了……

当地时间3月10日,美国《纽约邮报》撰写了一篇报道称“中国遭遇‘虫子雨’,居民被告知出门打伞”,并配上一则源自社交媒体的[详细]
2023-03-15

外交部发言人:中方对美韩军演动向表示严重关切

新华社北京3月14日电(记者马卓言、董雪)外交部发言人汪文斌14日说,中方对美韩军演动向表示严重关切,他表示当前朝鲜半岛形势高度复杂敏感,[详细]
2023-03-15

实时:魔盒怎么卸载视频教程_魔盒怎么卸载

1、恢复系统或把系统重装…魔盒的插件打开后右下角有个盒子的标志。2、先推出。3、然后删除魔兽目录下的interface和[详细]
2023-03-15

全球视点!伊腾富士子_伊东富士子74岁大战

1、伊东富士子,日本动作电影女演员,号称有史以来岁数最大的动作影片出演者。2、2008年出演第一部影片时已经超过70岁。[详细]
2023-03-15

全球快资讯:王者荣耀:为什么澜跟娜可露露的评分总是很低?哪怕你已经非常C

哈喽大家好,我是铃铛儿~不知道大家平时有没有玩打野这个位置,里面有两个英雄在评分机制里是比较特别的存在,他们就是澜跟娜可露露,这两个打[详细]
2023-03-14

【世界热闻】人民日报联合德施曼智能锁将派发亿元消费券!

2月28日,德施曼智能锁获国家权威媒体《人民日报》经济版面重磅报道,对其产品创新,技术升级,高端品牌的打造以及优化消费者[详细]
2023-03-14

红河县2023年保障性住房租赁补贴审核公示(第一批)

红河县2023年保障性住房租赁补贴审核公示(第一批)[详细]
2023-03-14

河南辉县市阳光里社区:提升治理效能点亮“共建共享星”|环球热资讯

近期以来,河南辉县市胡桥街道阳光里社区聚焦聚力“五星”支部创建,着力打造“共建共享星”特色亮点,有效激活社区治理活力。民主管理规范化[详细]
2023-03-14

计划3月底完工!金山这里的路面提升工程持续进行中

计划3月底完工!金山这里的路面提升工程持续进行中[详细]
2023-03-14
版权所有: 世纪制冷网 All Rights Reserved
京ICP备2021034106号-22
联系邮箱:55 16 53 8@qq.com