Wie finde ich heraus, ob ein goroutine getan wird, ohne zu blockieren?
-
20-09-2019 - |
Frage
Alle Beispiele, die ich bisher gesehen habe verwickeln blockieren das Ergebnis zu erhalten (über den <-chan
Operator).
Mein aktueller Ansatz beinhaltet einen Zeiger auf eine Struktur übergeben:
type goresult struct {
result resultType;
finished bool;
}
, die die goroutine nach Abschluss schreiben. Dann ist es eine einfache Sache, finished
zu prüfen, wann immer bequem. Haben Sie bessere Alternativen?
Was ich bin mit dem Ziel wirklich für ein Qt-Stil Signal-Slot-System. Ich habe das Gefühl, die Lösung fast trivial aussehen (chan
s haben viel von unerforschten Potential), aber ich bin noch nicht vertraut genug mit der Sprache zu Figur es aus.
Lösung
Sie können die Verwendung „Komma, ok“ Muster (siehe ihre Seite auf „ wirksam go „):
foo := <- ch; // This blocks.
foo, ok := <- ch; // This returns immediately.
Andere Tipps
Aussagen Wählen mehrere Kanäle auf einmal, wobei eine zufällige Verzweigung überprüfen können ( von denen, in denen die Kommunikation warten):
func main () {
for {
select {
case w := <- workchan:
go do_work(w)
case <- signalchan:
return
// default works here if no communication is available
default:
// do idle work
}
}
}
Für alle die Sende- und Empfangs Ausdrücke in der „select“ -Anweisung, der Kanal Ausdrücke ausgewertet werden, zusammen mit allen Ausdrücken, die angezeigt werden auf der rechten Seite des Sende Ausdrücke, in von oben nach unten um. Wenn eine der resultierenden Operationen können gehen, wird eine ausgewählt, und die entsprechende Kommunikation und Aussagen ausgewertet werden. Andernfalls, wenn es ein Standardfall, dass ausführt; wenn nicht, blockiert die Aussage bis eine der Kommunikation kann abgeschlossen.
Sie können auch Blick auf den Kanal sehen Puffer, wenn es etwas enthält unter Verwendung len:
if len(channel) > 0 {
// has data to receive
}
Damit wird den Kanalpuffer nicht berühren, im Gegensatz zu foo, gotValue := <- ch
, die einen Wert entfernt, wenn gotValue == true
.