【问题标题】:What is the preferred approach to do non-blocking select statement with channels in Go在 Go 中使用通道执行非阻塞选择语句的首选方法是什么
【发布时间】:2017-09-13 17:16:01
【问题描述】:

这是我想做的一个例子

func (zoo *Zoo) feedAnimals(food Food) {
    for animal := range zoo.Animals {
        select {
        case animal.EatChan() <- food:
        default: // Do nothing
        }
    }
}

动物的EatChan 有一个小缓冲区,有时调用feedAnimals 的频率比某些动物可以消耗食物的频率更高。发生这种情况时,如果我在 select 块中省略 default 语句,则 select 语句将阻止 for loop 并且其他饥饿的动物无法获得食物。所以我宁愿跳过吃饱的动物(即通道已达到其容量。)

但是,有一个空的default 对我来说感觉很奇怪。有一个更好的方法吗?

【问题讨论】:

  • 你可以增加缓冲区大小,这只会延迟问题,或者添加默认跳过备份的动物。对于这种情况,空的默认情况相当常见。
  • 是的,这可能会让人觉得很奇怪,但这是做你想做的事情的最佳方式。
  • @JimB 这是一个繁忙的循环吗?每次循环迭代针对不同的消费者。
  • @Adrian:你是对的,出于某种原因,我将 hat 视为一个空的 for 循环。
  • “有一个空的默认值对我来说感觉很奇怪”。习惯就好了。

标签: go channels


【解决方案1】:

但是,我觉得有一个空的默认值很奇怪。

不应该。

有没有更好的方法来做到这一点?

没有。

你已经做得很好了。空的默认值不是“什么都不做”语句,而是“不阻塞”语句。这只是非阻塞选择如何工作的语义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 2013-12-28
    相关资源
    最近更新 更多