doumaojin4008 2016-08-31 15:08
浏览 179
已采纳

在Golang中实现“事件”(带有通知者/接收者)的概念?

I'm wondering what is the proper way to handle the concept of "events" (with notifiers/receivers) in Golang. I suppose I need to use channels but not sure about the best way.

Specifically, I have the program below with two workers. Under certain conditions, "worker1" goes in and out of a "fast mode" and notify this via channels. "worker2" can then receive this event. This works fine, but then the two workers are tightly coupled. In particular, if worker2 is not running, worker1 gets stuck waiting when writing to the channel.

What would be the best way in Golang to implement this logic? Basically, one worker does something and notify any other worker that it has done so. Whether other workers listen to this event or not must not block worker1. Ideally, there could be any number of workers that could listen to this event.

Any suggestion?

var fastModeEnabled = make(chan bool)
var fastModeDisabled = make(chan bool)

func worker1() {
    mode := "normal"
    for {
        // under some conditions:
        mode := "fast"
        fastModeEnabled <- true

        // later, under different conditions:
        mode := "normal"
        fastModeDisabled <- true
    }
}

func worker2() {
    for {
        select {

        case <-fastModeEnabled:

            fmt.Println("Fast mode started")

        case <-fastModeDisabled:

            fmt.Println("Fast mode ended")

        }
    }
}

func main() {
    go worker2()
    go worker1()

    for {}
}
  • 写回答

1条回答 默认 最新

  • duandu2980 2016-08-31 17:23
    关注

    Use a non-blocking write to the channel. This way if anyone is listening they receive it. If there is no one listening it doesn't block the sender, although the event is lost.

    You could use a buffered channel so that at least some events are buffered if you need that.

    You implement a non-blocking send by using the select keyword with a default case. The default makes it non-blocking. Without the default case a select will block until one of its channels becomes usable.

    Code snippit:

    select {
        case ch <- event:
            sent = true
        default:
            sent = false
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 路易威登官网 里边的参数逆向
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?
  • ¥50 需求一个up主付费课程
  • ¥20 模型在y分布之外的数据上预测能力不好如何解决
  • ¥15 processing提取音乐节奏
  • ¥15 gg加速器加速游戏时,提示不是x86架构
  • ¥15 python按要求编写程序
  • ¥15 Python输入字符串转化为列表排序具体见图,严格按照输入
  • ¥20 XP系统在重新启动后进不去桌面,一直黑屏。