首页 > 解决方案 > Goroutines 选择范围循环

问题描述

我想生成一个 goroutine 来收听两个类型的频道chan intchan os.Signal. 我希望行为具体取决于在任一频道上收到的内容。这意味着有些os.Signal可能会导致os.exit()有些可能不会,有些int接收到chan int的可能会打印一条语句,有些可能会调用一个函数,所以我需要这个 gorountine 始终运行,因为行为不同。我希望这一切都由一个功能来处理。

我很难弄清楚如何在语法上实现这一目标。看起来我不能在块内有循环,也不能在range循环内select有一个selectrange。我在网上找不到任何关于此的资源。有人可以给我一个例子吗?

标签: goconcurrencychannelgoroutine

解决方案


您可以将select语句放入for循环中(这是语言规范中的示例之一)。与for...range循环不同,这将让您从两个通道中读取。如果其中一个通道关闭,它也不会自动终止。当你从一个封闭的通道接收时,一个封闭的通道总是准备好接收并且总是产生一个零值,并且它有一个二值形式告诉你通道是否打开。

您的功能可能看起来很松散

func HandleStuff(numbers <-chan int, signals <-chan os.Signal) {
    var goingToExit bool
    for {
        select {
        case n := <-numbers:
            if n == 0 {
                fmt.Printf("zero\n")
            } else if n == 1 {
                goingToExit = true
            }
        case sig, ok := <-signals:
            if !ok { // the channel is closed
                return
            } else if goingToExit {
                os.Exit(0)
            }
        }
    }
}

推荐阅读