Wie zu wissen, ein gepufferter Kanal ist voll? Ich weiß nicht, dass ich blockiert werden soll, wenn der gepufferte Kanal voll ist, stattdessen entscheide ich mich dafür, das Element, das an den gepufferten Kanal gesendet wurde, fallen zu lassen.Golang - Wie ein gepufferter Kanal ist voll
Antwort
Sie können die select
statement mit einem Standardwert verwenden. Falls es nicht möglich, jeden der Fälle zu tun, wie zu einem vollen Kanal zu senden, tut die Anweisung den Standard:
package main
import "fmt"
func main() {
ch := make(chan int, 1)
// Fill it up
ch <- 1
select {
case ch <- 2: // Put 2 in the channel unless it is full
default:
fmt.Println("Channel full. Discarding value")
}
}
Ausgang:
Kanal voll. Wegwerfen Wert
Spielplatz:http://play.golang.org/p/1QOLbj2Kz2
prüfen ohne
Sendet Es ist auch möglich, die Anzahl der Elemente in einem Kanal unter Verwendung len(ch)
Warteschlangen zu überprüfen, wie sie in den Go specifications angegeben. In Verbindung mit cap
können wir überprüfen, ob ein Kanal voll ist, ohne Daten zu senden.
if len(ch) == cap(ch) {
// Channel was full, but might not be by now
} else {
// Channel wasn't full, but might be by now
}
Beachten Sie, dass das Ergebnis des Vergleichs durch die Zeit ungültig werden kann, geben Sie den if
Block
Aber was, wenn man nur überprüfen möchte, ob der Puffer voll ist, _nicht_ daran schreiben, auch wenn es nicht ist? Gibt es eine Möglichkeit, das zu tun? – Tom
@Tom Sie können tatsächlich testen, ob len (ch) == cap (ch) {...} 'wo' len (ch) 'ist die Anzahl der Elemente im Kanal und' cap (ch) 'ist die Kapazität . Es ist jedoch möglicherweise ungültig, wenn Sie den if-Block eingeben. – ANisus
groß - jetzt ist das eine komplette Antwort! – Tom
stattdessen ich wähle das Element in dem gepufferten Kanal gesendet fallen zu lassen.
, dass "überquellenden Kanal" genannt wird, und Sie finden Anisus Antwort implementiert in eapache/channels/overflowing_channel.go
:
for elem := range ch.input {
// if we can't write it immediately, drop it and move on
select {
case ch.output <- elem:
default:
}
}
close(ch.output)
Aber das Projekt eapache/channels implementiert andere Strategien als auch:
OverflowingChannel
implementiert dieChannel
Schnittstelle auf eine Weise, die den Schreiber niemals blockiert.
Wenn ein Wert in einenOverflowingChannel
geschrieben wird, wenn sein Puffer voll ist
(oder in einem ungepufferten Fall, wenn der Empfänger nicht bereit ist), dann wird dieser Wert einfach verworfen.
Für das entgegengesetzte Verhalten (das älteste Element verwirft, nicht die neueste) sehen
RingChannel
.
Eine gute Antwort. Überlaufende Kanäle, die entweder das älteste oder das neueste Element verlieren, können manchmal wichtige Werkzeuge in Ihrer Toolbox sein. Betrachten Sie einen Ring von Goroutines: normalerweise gibt jede Schleife (a.k.a * cycle *) das Risiko eines Deadlocks. Das Ändern eines der Kanäle zu einem Überlauf behebt dieses Problem. Einige Ereignisse zu verlieren ist nicht wichtig, wenn sie die Art sind, die veraltet werden kann, können leicht ersetzt werden. Es gibt (natürlich) andere Möglichkeiten, das gleiche Deadlock-Problem zu beheben. –
Ein anderes nützliches Beispiel, über das ich gestolpert bin, war this nifty implementation von Ring Buffer.
Das Zitat aus der Quelle:
Die Idee ist einfach: Verbinden zwei gepufferte Kanäle durch eine Goroutine, die Nachrichten aus dem Eingangskanal zu dem abgehenden Kanal weiterleitet. Wenn eine neue Nachricht nicht auf dem ausgehenden Kanal platziert werden kann, nehmen Sie eine Nachricht aus dem ausgehenden Kanal ( ist die älteste Nachricht im Puffer), legen Sie sie ab und legen Sie die neue Nachricht in den neuen freigegebenen Ausgang Kanal.
Check out this C version auch ...
Verwenden len(channel)
zu überprüfen, wie viele Elemente zur Zeit im Kanal ist und vergleichen Sie das mit cap(channel)
, seine Kapazität:
func TestChannelFull(t *testing.T) {
chansize := 100
ch := make(chan bool, chansize)
t.Log(cap(ch))
t.Log(len(ch))
for len(ch) < cap(ch) {
ch <- true
}
t.Log(len(ch))
t.Log("quit because channel is full")
}
init_test.go:25: 100
init_test.go:26: 0
init_test.go:30: 100
init_test.go:31: quit because channel is full
PASS
- 1. Golang Fifo gepufferter Kanal
- 2. Gepufferter/ungepufferter Kanal
- 3. Wann wird ein gepufferter Kanal verwendet?
- 4. Erstelle ein Stück gepufferten Kanal in Golang
- 5. Golang handlefunc mit Kanal
- 6. periodisch spülen kanal in golang
- 7. Es ist möglich, eine golang Kanal in eine Vorlage
- 8. Ist der gepufferte Kanal von Go gesperrt?
- 9. Wie wird der gepufferte Kanal in Golang richtig gehandhabt?
- 10. Kanalspeicher ist beim Start voll
- 11. Ist TarArchiveInputStream gepufferter oder ungepufferter Eingabestream?
- 12. Golang - Was ist Kanalpuffergröße?
- 13. Die Ereignisprotokolldatei ist voll
- 14. CodeCahe ist voll Java7
- 15. Schließen Sie den Golang-Kanal mit mehreren Werten
- 16. Warum schreibt mein Golang-Kanal immer für immer?
- 17. Warum mein Golang-Kanal einen Dead-Lock-Fehler auslöst?
- 18. TF30042: Die Datenbank ist voll
- 19. mySQL temporäre Tabelle ist voll
- 20. Panel Überschrift ist nicht voll
- 21. Suche gepufferter Prozentsatz von Videoelement
- 22. mod_rewrite ist nicht voll funktionsfähiges
- 23. Android: Cursor Fenster voll ist
- 24. wie voll Code schreiben
- 25. Golang was ist "%! S"
- 26. Wie voll Symlink Pfad
- 27. wie voll Visual Studio
- 28. TypeError: 'Kanal' ist ein ungültiges Schlüsselwort-Argument für diese Funktion
- 29. Byte-Array zu gepufferter Bildkonvertierung langsam
- 30. Erkennen, dass der Stapel voll ist
Die Prämisse der Frage ist, dass du vermeiden willst, dass der Kanal jemals voll wird. Aber die Tatsache, dass Kanäle * sich synchronisieren können und daher beide Enden blockieren, ist ein wichtiger Teil des CSP-Denkens. Versuchen Sie nicht zu sehr zu verhindern, dass Ihre Puffer voll werden, bis Sie die Synchronisation besser verstehen. Versuchen Sie als Übung, mehrere Probleme nur mit * ungepufferten * Kanälen zu lösen. Dann können Sie sehen, wie das Hinzufügen von Pufferung im Nachhinein eine Leistungsverbesserung für ein bereits funktionierendes System sein kann. (Es gibt gelegentlich Fälle, in denen zu viel Pufferung sogar die Leistung verringern könnte.) –