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 identifier of an instance of 类 was altered from xx to xx错误
  • ¥100 反编译微信小游戏求指导
  • ¥15 docker模式webrtc-streamer 无法播放公网rtsp
  • ¥15 学不会递归,理解不了汉诺塔参数变化
  • ¥30 软件自定义无线电该怎样使用
  • ¥15 R语言mediation包做中介分析,直接效应和间接效应都很小,为什么?
  • ¥15 Jenkins+k8s部署slave节点offline
  • ¥15 如何实现从tello无人机上获取实时传输的视频流,然后将获取的视频通过yolov5进行检测
  • ¥15 WPF使用Canvas绘制矢量图问题
  • ¥15 用三极管设计一个单管共射放大电路