今天,让我们来看看golang频道中另一个非常重要的概念。之前介绍goroutines的时候,我们问了一个问题。在我们启动了几个goro tine之后,如何保持goro tine之间的通信?
要回答这个问题,我们需要使用渠道。
频道
海峡的英文是channel,golang的关键词是chan。其目的是在goroutines之间传输数据。在这里,你可能要问,为什么要在goroutines之间传输数据?功能不能转移吗?
因为正常传输数据可以直接以参数的形式传输,所以只有在并发场景下,当多个线程相互隔离时,才需要一个特殊的结构来传输数据。
Chan看起来很奇怪,在其他语言中几乎没有出现过,但是它的原理和使用都很简单。
先看看它的用途。首先,定义一个chan,或者像往常一样,通过make关键字创建它。正如我们之前提到的,golang的设计原则之一就是边省边省,简单中求简单。从这个make关键字我们可以看出,它可以创建太多的东西,比如创建一个切片、一个地图和一个频道。
所以当我们想要创造一个变化时,我们可以通过make来实现。
Ch := make(chan int)我们在chan之后跟随一个类型,它指示由该信道传输的数据类型。如果你想传输任何类型,你可以使用我们之前谈到的接口{}。
在Chan被创建之后,我们从它那里获取数据或者把数据放入其中是非常简单的。简单到没有api,直接用生动的传输语句就可以了。
例如,我们现在有一个变更,它是ch,我们想把数据放进去。我们可以做这个。
我们用箭头表示数据的流向,不是很生动直观吗?
街区
但还没有结束。chan的一个关键点是chan的使用受阻。也就是说,在我们可以传入一条数据之前,下游从chan获取一条数据。否则,传输数据的代码将一直等待chan Qing 空。
同样,如果我们定义一个从chan读取数据的语句,如果当前chan是空,它将阻塞等待,直到chan中有数据。
所以我们知道chan的使用场景需要一个生产者和一个消费者。让我们看一个golang的官方例子:
package mainimport "fmt"func sum(s []int, c chan int) { sum := 0 for _, v := range s { sum += v } c我们启动了两个goroutines来求和并返回数组。goroutines产生的数据不能直接返回,只能通过chan传输。Chan传输需要下游消耗,因此上述两个goroutine的数据将被传输到x,y:
我前面说过,chan的传输被阻断了,所以这句话就要等到上面两个goroutine都计算出来了。
如果你看到的东西有点混乱,你觉得好像你已经理解了或者没有理解,那么一个非常简单的方法就是在你理解的时候改变这个使用场景。把chan的使用场景想象成我们之前介绍的生产者-消费者设计模式,chan的角色实际上是队列。
生产者向队列传输数据,消费者消费数据。唯一不同的是,这个队列的容量是1,只有生产和消费都准备好了,才能进行数据传输。
陈氏缓冲器
如前所述,chan的容量只有1,只有消费者和生产者都准备好了,才能传输数据。我们也可以缓冲变化。如果消费者没有时间消费所有数据,那么允许生产者将数据临时存储在chan中,直到chan满了才会被阻止。
用法也很简单。当我们通过make创建chan时,我们可以再添加一个参数来表示容量,这与我们以前创建切片的原因非常相似。
Ch := make(chan int, 100)例如,我们创建了一个缓冲区为100的通道。
不过多说一句,其实这种情况并不是很常见,原因也很简单。因为上下游的消费情况是统一的,如果生产者生产太快,消费者跟不上,即使暂时存放在缓冲区,迟早也会被堵死。
关闭
当我们使用完通道后,我们可以通过close语句关闭它。
关闭只能在生产端执行,如果在消费端使用关闭通道,则会触发死机。当我们从chan接收数据时,我们可以添加一个参数来确定通道是否关闭。
v, ok :=这样就可以判断chan的关闭时间。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 ZLME@xxxxxxxx@hotmail.com 举报,一经查实,立刻删除。