Ungepufferte Kanäle blockieren Empfänger, bis Daten auf dem Kanal verfügbar sind. Es ist mir nicht klar, wie sich dieses Blocking mit mehreren Empfängern auf dem gleichen Kanal verhält (sagen wir mal bei der Verwendung von Goroutines). Ich bin sicher, sie würden alle blockieren, solange keine Daten über diesen Kanal gesendet werden.
Aber was passiert, nachdem ich einen einzelnen Wert an diesen Kanal gesendet habe? Welcher Empfänger/goroutine wird die Daten bekommen und somit entsperren? Alle von ihnen? Der erste in der Reihe? Zufällig?Mehrere Empfänger auf einem einzelnen Kanal. Wer bekommt die Daten?
Antwort
Ein einzelnes zufälliges (nicht deterministisches) wird es erhalten.
Standardmäßig ist die Goroutinerkommunikation synchronous
und unbuffered
: Senden wird erst abgeschlossen, wenn ein Empfänger den Wert akzeptiert. Es muss ein Empfänger bereit sein, um Daten von dem Kanal zu empfangen, und der Sender kann ihn dann direkt an den Empfänger übergeben.
So Kanal-Sende-/Empfangsvorgänge blockiert, bis die andere Seite ist bereit:
1. Ein Sendevorgang auf einem Kanal blockiert, bis ein Empfänger für den gleichen Kanal verfügbar ist: wenn es kein Empfänger für den Wert unter ch
kann kein anderer Wert in den Kanal eingegeben werden. Und umgekehrt: In ch
kann kein neuer Wert gesendet werden, wenn der Kanal nicht leer ist! Der Sendevorgang wartet also, bis ch
wieder verfügbar wird.
2. Ein Empfangsvorgang für einen Kanal blockiert, bis ein Sender für denselben Kanal verfügbar ist: Wenn kein Wert im Kanal vorhanden ist, blockiert der Empfänger.
Dies wird im folgenden Beispiel veranschaulicht:
package main
import "fmt"
func main() {
ch1 := make(chan int)
go pump(ch1) // pump hangs
fmt.Println(<-ch1) // prints only 0
}
func pump(ch chan int) {
for i:= 0; ; i++ {
ch <- i
}
}
Da es keine Empfänger nur die erste Zahl goroutine hängt und Druck ist.
Um dies zu umgehen, müssen wir eine neue goroutine definieren, die aus dem Kanal in einer Endlosschleife liest.
func receive(ch chan int) {
for {
fmt.Println(<- ch)
}
}
Dann in main()
:
func main() {
ch := make(chan int)
go pump(ch)
receive(ch)
}
- 1. Wer erhält diese Absicht (keine Empfänger registriert)
- 2. jQuery Autocomplete auf verschiedenen Daten in einem einzelnen Textfeld
- 3. htaccess für mehrere Domains auf einem einzelnen Webhost
- 4. Wie kann ich mehrere Optionsfeldgruppen auf einem einzelnen Formular erstellen?
- 5. Datenbankentwurf, mehrere Attribute in einem einzelnen Feld
- 6. Mail an mehrere Empfänger ohne Empfänger senden, die anderen Menschen zu sehen, ich es
- 7. SMS an mehrere Empfänger senden
- 8. Wer die Socket-Verbindung herunterfährt
- 9. Mehrere Formulare auf einer einzelnen Seite - JQuery
- 10. Mehrere Entwickler auf demselben einzelnen iTunes-Konto
- 11. Guice: injizieren unterschiedliche Implementierung je nachdem wer es bekommt?
- 12. Visual Studio: Wer schreibt auf die Konsole?
- 13. YouTube Analytics-API: Suchen nach eindeutigen Besuchern auf einem Kanal
- 14. I2C-Slave-Empfänger auf stm32f4
- 15. Wie schließe ich einen Kanal, auf dem mehrere Goroutines senden?
- 16. Mehrere Diagramme aus einem einzelnen Google-Tabellenblatt werden nicht angezeigt.
- 17. Wer übernimmt die IErrorInfo?
- 18. iOS: Mehrere Ansichten Zugriff auf die gleichen Daten - wie auf?
- 19. Angularjs Filter mit einzelnen Schlüssel mehrere Werte der übergeordneten Daten
- 20. Wie zeichne ich mehrere Y-Werte für einen einzelnen X-Wert in einem einzelnen Gnuplot-Fenster?
- 21. Wie verschlüsselt man eine Nachricht für mehrere Empfänger?
- 22. Mehrere Instanzen eines einzelnen Benutzerformulars/die Notwendigkeit von Zeigern
- 23. SQL zum Aufteilen einer einzelnen Zeile in mehrere basierend auf einem Zählwert?
- 24. Wie verbindet man mehrere Datenbanken auf einem einzelnen Server mit JDBC?
- 25. Wie fügt man mehrere listViews zu einem einzelnen listView hinzu?
- 26. Mehrere jQuery/DOM-Elemente zu einem einzelnen jQuery-Objekt hinzufügen
- 27. Mehrere Client-Sockets zu einem einzelnen Server C++
- 28. Mehrere Textzeilen zu einer einzelnen Karte
- 29. Abfrage mehrere Datenbanken mit einzelnen ado.net Abfrage
- 30. Anzeige mehrerer Unterberichte in einem einzelnen Berichtsobjekt
Race Condition? Ist es sicher zu tun? –
Ja sicher, es ist nur rassig, welche Goroutine das Element bekommt. – inf
Ich würde es nicht eine "Race Condition" nennen. Dieser Begriff ist konventionell definiert, um unbeabsichtigtes Verhalten aufgrund eines unsicheren gleichzeitigen Zugriffs einer Variablen anzuzeigen. Kanäle sind so ausgelegt, dass sie gleichzeitig sicher zugänglich sind, und es gibt nichts Falsches an mehreren Lesegeräten auf einem ungepufferten Kanal. – JimB