channel 的 range 和 select 比较
本文是对 Channels in Go - range and select 的学习
range
在 goroutine 之间使用 channel 通信时,数据接收方总是面临这样的问题:什么时候停止等待数据?还会有更多的数据么,还是所有内容都完成了?我应该继续等待还是该做别的了?对于这个问题,一个可选的方式是,持续的访问数据源并检查channel是否已经关闭,但是这并不是高效的解决方式。Go提供了range
关键字,将其使用在channel上时,会自动等待channel的动作一直到channel被关闭。
下面通过一段示例代码来说明:
1 | package main |
1 | 输出结果 |
a 这个 goroutine 一直向 channel 内传递数据,直到这个 channel 被关闭前,b 这个 goroutine 都会通过 range
这个关键字阻塞在循环中一直等待 channel 中的数据。通过这个例子还可以看出,for range
可以接收 channel 中的数据,不然 c 作为一个无缓冲 channel,a 不可能向其中一直发送数据。
select
select
关键字用于多个channel的结合,这些channel会通过类似于 are-you-ready polling 的机制来工作。select
中会有case
代码块,用于发送或接收数据——不论通过<-
操作符指定的发送还是接收操作准备好时,channel也就准备好了。在select
中也可以有一个default
代码块,其一直是准备好的。那么,在select
中,哪一个代码块被执行的算法大致如下:
- 检查每个
case
代码块 - 如果任意一个
case
代码块准备好发送或接收,执行对应内容 - 如果多于一个
case
代码块准备好发送或接收,随机选取一个并执行对应内容 - 如果任何一个
case
代码块都没有准备好,等待 - 如果有
default
代码块,并且没有任何case
代码块准备好,执行default
代码块对应内容
- Post title:channel 的 range 和 select 比较
- Post author:洪笳淏
- Create time:2022-03-19 18:14:00
- Post link:https://jiahaohong1997.github.io/2022/03/19/channel 的 range 和 select 比较/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
Comments