Go 语言 select 语句的优先级

Go 语言中,配合通道“channel”的读写操作,特地提出一个 select语句,用于多个 channel 的并发读写操作。例如:

上述代码的意思是,同时在 a 和 b 中选择,哪个有内容就从哪个读,否则输出“No data”。由于 channel 的读写操作是阻塞操作,使用 select语句可以避免单个 channel 的阻塞。 default的作用是避免两个 channel 同时阻塞。

有一个问题, selectcase顺序是随机的,并不是按代码中写的顺序。于是就产生了优先级的问题。比如我想先从 a 读取,a 没有内容的时候,再从 b 读取,就不能用上述的方式了。这种情况下的逻辑要稍微麻烦一点:

描述起来倒是蛮简单,先从 a 读,没数据的话再从两个一起读。这种方式对于读和写操作都适用, default是否需要取决于应用场景。


8 条评论 添加

    1. 因为在有 default 的情况下,只要 a 里面没有数据,就会立即跳转到 default。有一种情况是,调用函数的时候,a、b 中都没有数据,但过了一会之后 a 中的数据先来,b 的数据后来。根据定义,这时候还是应该返回 a 中的数据,于是在第二个 select 中需要同时读取 a 和 b。

          1. 我是指执行外层 select 时 a 里边没数据,再执行里边的 select 时 a 又已经有了新过来的数据,此时 b 中也可能已经有数据,这时就不是 a 优先了。

          2. 之前的回复还没出现,我假设它发送成功了好了。

            即使你设定这个优先只是看外层 select 执行时哪个里边有数据,还是可能出现一个情况:执行外层时,a b 都没数据;执行里层时,a b 都有数据了。

            当然如果你的需求不需要保证 100% 优先的话可以忽略这个小瑕疵,如果这个顺序是很重要的话,就是个很讨厌的 race condition 了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注