Adressierung der Priorität in Go-select-Anweisungen
Bei der Verwendung von select-Anweisungen in Go ist die Reihenfolge der Fallauswertung normalerweise nicht deterministisch. In einigen Szenarien müssen wir jedoch möglicherweise die Ausführung bestimmter Fälle priorisieren.
Priorität mit Kontextstornierung
Betrachten Sie den folgenden Code, in dem wir ordnungsgemäß herunterfahren möchten ein Heartbeat-Sender, wenn der Kontext abgebrochen wird:
func sendRegularHeartbeats(ctx context.Context) { for { select { case <-ctx.Done(): return case <-time.After(1 * time.Second): sendHeartbeat() } } }
Wenn der Kontext jedoch sofort geschlossen wird, kann der Code möglicherweise immer noch a übertragen Herzschlag, bevor der Fall „Fertig“ ausgeführt wird.
Lösung: Vorrang mit Hilfskanälen
Ein Ansatz zur Lösung dieses Problems besteht darin, einen Hilfskanal zu verwenden, um die Kontextlöschung zu priorisieren case:
func sendRegularHeartbeats(ctx context.Context) { done := make(chan struct{}) go func() { <-ctx.Done() close(done) }() for { select { case <-done: return case <-time.After(1 * time.Second): sendHeartbeat() } } }
In diesem Fall stellt der Done-Kanal sicher, dass der Fall „ctx.Done()“ beim Kontext zuerst ausgewertet wird wird abgebrochen.
Zusätzliche Überlegungen
Diese Lösung verbessert zwar die Priorität, schließt jedoch nicht vollständig die Möglichkeit aus, dass ein Heartbeat gesendet wird, bevor der Fall „Fertig“ ausgeführt wird. Für ein wirklich synchronisiertes Herunterfahren sollten Sie die Verwendung von Synchronisierungsprimitiven wie atomaren Variablen oder Mutexes in Betracht ziehen, um sicherzustellen, dass die Heartbeat-Übertragung sofort nach dem Abbrechen des Kontexts beendet wird.
Das obige ist der detaillierte Inhalt vonWie priorisiert man Fälle in Gos „select'-Anweisungen für die deterministische Ausführung?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!