channel是什么意思(简介channel常见用法)

channel是什么意思(简介channel常见用法)

文章目录[隐藏]

今天,我们来看看golang中另一个非常重要的概念——通道。之前介绍Goroutines的时候,我们问了一个问题。在我们启动了多个go routine之后,我们如何保持go routine之间的通信?

要回答这个问题,你需要用到渠道。

频道

信的英文是channel,golang的关键词是chan。其目的是在goroutines之间传输数据。在这里,你可能要问,为什么一定要在goroutines之间?函数不能传输数据吗?

因为正常的传输数据可以直接以参数的形式传输,只有在并发的场景下,当多个线程相互隔离时,才需要一个特殊的结构来传输数据。

Chan看起来很奇怪,在其他语言中几乎没有出现过,但是原理和用法都很简单。

我们先来看看它的用途。首先,定义一个chan,或者像往常一样,通过make关键字创建它。我们之前提到过,golang的设计原则之一就是省钱,简单就是简单。从这个make关键字可以看出,它能创造的东西太多了。它可以创建切片、地图和通道。

所以当我们想创造一个改变时,我们可以通过make来实现。

Ch := make(chan int)

我们遵循chan之后的最后一种类型,它表示该信道传输的数据类型。如果要传输任何类型,可以使用我们之前说的接口{}。

创建Chan后,我们很容易从中获取数据或向其中放入数据。简单到没有api。就用传神的语句吧。

例如,我们现在有一个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 +=&嘉文社百科nbsp;v } c 

我们启动了两个goroutines来对数组求和并返回它。goroutines产生的数据不能直接返回,所以只能以chan的形式传输。Chan需要传输下游消费,所以上面两个goroutine的数据会传输到x,y:

如前所述,chan的传输被阻止,所以此语句将等到上述两个goroutine计算完毕。

如果你看起来有点迷茫,感觉好像懂了什么但又不懂,那么一个很简单的方法就是在懂了的情况下,对这个使用场景做一个改变。把chan的使用场景想象成我们之前介绍的生产者-消费者设计模式,chan在其中的角色实际上是队列。

数据被传输到生产者队列,消费者进行消费。唯一的区别是这个队列的容量是1,只有当生产者和消费者都准备好了,数据传输才会发生。

陈氏缓冲液

如前所述,chan的容量只有1,只有在消费者和生产者都准备好的情况下才能传输数据。我们也可以缓冲chan。如果消费者没有时间消耗所有数据,则允许生产者首先将数据临时存储在chan中,而不进行阻塞,并且仅当chan已满时才进行阻塞。

用法也很简单。当我们通过make创建chan时,我们可以添加一个额外的参数来表示容量,这与我们之前创建切片的原因类似。

Ch := make(chan int, 100)

例如,我们创建一个缓冲区为100的通道。

但是换个角度来说,其实这种情况并不是很常见,原因很简单。因为上下游消费情况是统一的,如果生产者生产太快,消费者跟不上,即使暂时存放在缓冲区,迟早也会被堵死。

关闭

当我们使用完频道后,我们可以通过Close Gavin Encyclopedia语句来关闭它。

这个关闭操作只能在制作端进行,如果在消费者加文社的百科端使用关闭通道会引发恐慌。当我们从chan接收数据时,我们可以添加一个参数来判断通道是否关闭。

v, ok := 

所以我们可以判断陈什么时候关门。

以上就是由优质生活领域创作者 嘉文社百科网小编 整理编辑的,如果觉得有帮助欢迎收藏转发~