当我接收到没有特定顺序的“退出”信号时,除了调用其他功能外,我还需要按需停止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()
}
答案 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?