channel是什么意思(简介channel常见用法)
今天我们来看看golang当中另一个很重要的概念——信道 。我们之前介绍goroutine的时候曾经提过一个问题,当我们启动了多个goroutine之后,我们怎么样让goroutine之间保持通信呢?
要回答这个问题就需要用到信道 。
channel
信道的英文是channel,在golang当中的关键字是chan 。它的用途是用来在goroutine之间传输数据,这里你可能要问了,为什么一定得是goroutine之间传输数据呢,函数之间传递不行吗?
因为正常的传输数据直接以参数的形式传递就可以了,只有在并发场景当中,多个线程彼此隔离的情况下,才需要一个特殊的结构传输数据 。
Chan看起来比较怪,在其他语言当中基本没有出现过,但是它的原理和使用都非常简单 。
【channel是什么意思(简介channel常见用法)】我们先来看它的使用,首先是定义一个chan,还是老规矩,通过make关键字创建 。我们之前也提过,golang当中的一个设计原则就是能省则省,能简单则简单 。从这个make关键字就看得出来,它可以创建的东西太多了,既可以创建一个切片,也可以创建map,还可以创建信道 。
所以当我们要创建一个chan的时候,可以通过make实现 。
Ch := make(chan int)
我们在chan后面跟上一个类型,表示这个信道传输的数据类型 。如果你想要传输任何类型呢,那可以用我们之前说过的interface{} 。
Chan创建了之后,我们想要从其中获取数据或者是把数据放入其中也非常简单,简单到都没有api,直接用形象的传输语句就可以了 。
比如我们现在有一个chan是ch,我们想要放入数据,我们可以这样ch <- a 。我们想要从ch当中获取数据,我们可以v := <- ch 。
我们用箭头表示数据的流动,是不是很形象很直观呢?
阻塞
但是还没完,chan有一个很关键的点在于,chan的使用是阻塞的 。也就是说下游从chan当中拿走一个数据我们才可以传入一个数据 。否则的话,传输数据的代码就会一直等待chan清空 。
同样,如果我们定义了一个从chan当中读取数据的语句,假如当前的chan是空的话,那么它也会一直阻塞等待,直到chan当中有数据了为止 。
所以我们就知道了,chan的使用场景当中需要一个生产方,也需要一个消费方 。我们来看一个golang官方的一个例子:
package mainimport "fmt"func sum(s []int, c chan int) { sum := 0 for _, v := range s { sum += v } c <- sum // 将和送入 c}func main() { s := []int{7, 2, 8, -9, 4, 0} c := make(chan int) go sum(s[:len(s)/2], c) go sum(s[len(s)/2:], c) x, y := <-c, <-c // 从 c 中接收 fmt.Println(x, y, x+y)}
我们启动了两个goroutine去对数组进行求和并进行返回,goroutine生产的数据是没办法直接return的,所以只能通过chan的形式传输出来 。chan传输出来需要下游消费,所以上面两个goroutine的数据会传输到x, y: <-c, <-c 这一句语句当中 。
前面说过了,chan的传输是阻塞的,所以这一句语句会一直等待,直到上面两个goroutine都计算完成了为止 。
如果你看的有些发蒙,觉得好似有些理解了又好似没有的话,那么很简单的一个办法是在理解的时候把这个使用场景做一个变幻 。把chan的使用场景想象成我们之前介绍过的生产者消费者设计模式,chan在其中扮演的角色其实就是队列 。
- 大家都在刷“张同学”,到底刷的是什么?
- 从放烟花到弹钢琴,疫情防控的“温情”背后是什么
- 动解|元宇宙,几个意思?
- 殷世航和韩安冉的关系怎么样 连麦是什么时候
- 我慢慢的听雪落下的声音是什么歌 《延禧攻略》插曲及片尾曲
- 萌德卡妹宣布分手 萌德卡妹为何分手是什么时候交往的
- 芈月传芈瑶第几集出现 芈瑶最后的结局是什么
- 何炅谢娜是什么关系 何炅的父亲何畏为什么被叫老赖
- 白百何为什么叫京圈太子妃 白百何和文章是什么关系
- 闪光的乐队是什么类型的综艺 闪光的乐队嘉宾阵容有谁
