登录
首页 >  Golang >  Go问答

Goroutine 使用范围循环进行选择

来源:stackoverflow

时间:2024-03-16 18:03:25 379浏览 收藏

在 Go 语言中,使用 goroutine 并发处理多个任务时,开发者可能会遇到需要同时监听多个通道的情况。如果通道类型不同,并且接收到的内容需要触发不同的操作,那么如何实现这一目标就成为一个挑战。本文将介绍如何使用 for 循环和 select 语句组合,来优雅地处理这种场景,实现 goroutine 的选择性监听。通过将 select 语句放置在 for 循环中,可以持续监听多个通道,并根据接收到的内容采取不同的行动。这种方法允许 goroutine 持续运行,并根据通道中的数据动态调整行为。

问题内容

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

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


解决方案


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

你的函数可能看起来像这样

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)
            }
        }
    }
}

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>