Niepubliczne kanały blokują odbiorniki, dopóki dane nie będą dostępne na kanale. Nie jest dla mnie jasne, jak to blokowanie zachowuje się z wieloma odbiornikami na tym samym kanale (np. Przy korzystaniu z goroutinów). Jestem pewien, że wszyscy będą blokować tak długo, jak długo nie będą wysyłane dane na ten kanał.
Ale co się stanie, gdy wyślę pojedynczą wartość do tego kanału? Który odbiornik/goroutine otrzyma dane, a zatem odblokuje? Wszyscy? Pierwszy w kolejce? Losowy?Wiele odbiorników na jednym kanale. Kto otrzymuje dane?
Odpowiedz
Otrzyma je pojedynczy losowy (niedeterministyczny).
Domyślnie komunikacja z goroutine to synchronous
i unbuffered
: wysyłanie nie jest zakończone do momentu, aż odbiornik zaakceptuje wartość. Musi być odbiornik gotowy do odbioru danych z kanału, a następnie nadawca może przekazać go bezpośrednio do odbiornika.
Więc kanał wysyłania/odbierania operacje blokowania aż druga strona jest gotowa:
1. Operacja wyślij na ciągu bloków kanałowych aż odbiornik jest dostępna dla tego samego kanału: jeśli nie ma odbiorca dla wartości na ch
, żadna inna wartość nie może zostać umieszczona w kanale. I na odwrót: żadna nowa wartość nie może zostać wysłana w ch
, gdy kanał nie jest pusty! Tak więc operacja wysyłania będzie czekać, aż ch
stanie się ponownie dostępna.
2. Operacja odbierania dla bloków kanałów, dopóki nadawca nie jest dostępny dla tego samego kanału: jeśli nie ma wartości w kanale, odbiornik blokuje się.
Ilustruje to poniższy przykład:
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
}
}
Ponieważ nie ma odbiornik zawiesza goroutine i drukować tylko pierwszy numer.
Aby to obejść, musimy zdefiniować nową goroutine, która czyta z kanału w nieskończonej pętli.
func receive(ch chan int) {
for {
fmt.Println(<- ch)
}
}
Następnie w main()
:
func main() {
ch := make(chan int)
go pump(ch)
receive(ch)
}
- 1. Czy dwa procesy mogą być renderowane na jednym kanale OpenGL?
- 2. Wiele UITableViews na jednym UIView
- 3. Wiele na() lub przełącznik() w jednym na()
- 4. Wiele kanałów w jednym kanale RSS xml - czy jest to zawsze właściwe?
- 5. Wiele modeli ng na jednym polu wprowadzania?
- 6. Wiele krzywych ROC na jednym wykresie ROCR
- 7. Wykreśl wiele linii na jednym wykresie
- 8. Lista zainstalowanych pakietów na kanale
- 9. Posty na Facebooku na kanale rss?
- 10. Wiele UICollectionView w jednym kontrolerze
- 11. Wiele kolumn w jednym StaggeredGridView?
- 12. Wiele PickerViews w jednym widoku?
- 13. Wiele konstruktorów z jednym parametrem
- 14. Wiele repozytoriów w jednym katalogu
- 15. Jak powiązać dane z atrybutem * w kanale kątowym2?
- 16. Wiele suwaków z jednym oddzwanianiem
- 17. Wiele SELECT w jednym zapytaniu
- 18. Wiele kontrolerów z jednym modelem
- 19. Czy istnieje sposób na dodanie wielu odbiorników w Pythonie SMTPlib?
- 20. Który algorytm może racjonalnie redukować wiele list? ("kto zabił, kto" pro blem)
- 21. KnockOutJS - wiele modeli ViewModels w jednym widoku
- 22. Histogram Kibana - Wiele sparametryzowanych linii na jednym wykresie
- 23. Wiele klas wyrażeń w jednym pliku Java
- 24. Jak pobrać wszystkie dane w jednym zapytaniu
- 25. Wiele identyfikatorów w jednym zdarzeniu kliknięcia JavaScriptu
- 26. Wybierz wiele wierszy SQL w jednym rzędzie
- 27. Zmniejsz wszystkie wiadomości (~ 8K) na kanale
- 28. wybierz wiele wierszy w jednym wierszu wyników
- 29. jak znaleźć, kto blokuje, kto w SQL Server 2005
- 30. D3: Wiele układów sił w jednym SVG?
stan Race? Czy można to zrobić bezpiecznie? –
Tak, to po prostu gorsze, że goroutine dostaje żywioł. – inf
Nie nazwałbym tego "stanem wyścigu". Termin ten jest tradycyjnie definiowany, aby wskazać niezamierzone zachowanie z powodu niebezpiecznego współbieżnego dostępu do zmiennej. Kanały są zaprojektowane tak, aby były bezpiecznie dostępne jednocześnie i nie ma nic złego w wielu czytnikach na niebuforowanym kanale. – JimB