close(channel)用于实现观察者模式

时间:2018-09-17 07:30:15

标签: go observer-pattern

当我接收到没有特定顺序的“退出”信号时,除了调用其他功能外,我还需要按需停止HTTP服务器。

在尝试实现类似observer pattern之类的方法时,我发现创建频道非常方便(quit := make(chan struct{}),比如说“ 主题”,然后在每个的goroutine的“ 观察者”在该频道<-quit上监听,等待更改,然后继续。

我立即触发所有功能的方式是通过关闭通道close(quit)而不是通过写入通道来完成,到目前为止,我已经尝试过此方法,但仍想知道这种方法是否有缺点或是否存在是实现类似行为/模式的更好/惯用方式。

package main

import (
    "log"
    "net/http"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup

    srv := &http.Server{Addr: ":8080"}

    wg.Add(1)
    go func() {
        log.Println(srv.ListenAndServe())
        wg.Done()
    }()

    quit := make(chan struct{})
    go func() {
        <-quit
        if err := srv.Close(); err != nil {
            log.Printf("HTTP server Shutdown: %v", err)
        }
    }()

    wg.Add(1)
    go func() {
        <-quit
        log.Println("just waiting 1")
        wg.Done()
    }()

    wg.Add(1)
    go func() {
        <-quit
        log.Println("just waiting 2")
        wg.Done()
    }()

    <-time.After(2 * time.Second)
    close(quit)
    wg.Wait()
}

https://play.golang.org/p/uIfMJfN6xQy

1 个答案:

答案 0 :(得分:1)

我会说你的方式足够好,但缺乏优雅。

您可以使用#include <LiquidCrystal.h> LiquidCrystal lcd(1, 2, 4, 5, 6, 7); int limitSwitch = 13; int limitSwitch2 = 12; int state1 = LOW; int state2 = LOW; float centimeter = 0.050; float timeRequired = 0.000; float velocity = 0.000; float durationFloat = 0.000; unsigned long startTime; unsigned long endTime; unsigned long duration; byte timerRunning; void setup() { Serial.begin(9600); lcd.begin(16,2); pinMode(limitSwitch,INPUT); pinMode(limitSwitch2,INPUT); } void loop() { int val1 = digitalRead(limitSwitch); int val2 = digitalRead(limitSwitch2); lcd.clear(); if( val1 != state1 || val2 != state2 ) { state1 = val1; state2 = val2; if( state1 == 0 && timerRunning == 0 ) startTime = millis(); timerRunning = 1; if( state2 == 0 && timerRunning == 1) endTime = millis(); timerRunning = 0; duration = endTime - startTime; durationFloat = (float) duration; timeRequired = durationFloat / 1000; velocity = centimeter / timeRequired; lcd.setCursor(0, 0); lcd.print("Speed: "); lcd.print(velocity); lcd.setCursor(0, 1); Serial.print("Speed in m/s = "); Serial.println(velocity,7); // lcd.print("Speed: "); lcd.print(velocity); delay(1000); } } 来实现所需的行为:

https://golang.org/pkg/sync/#Cond
How to correctly use sync.Cond?