pracuję nad jednoczesnym biblioteki Go, i natknąłem się na dwóch różnych wzorcach synchronizacji między goroutines których wyniki są podobne:Jaka jest przewaga synchronizacji.WaitGroup nad kanałami?
Korzystanie Waitgroup
var wg sync.WaitGroup
func main() {
words := []string{ "foo", "bar", "baz" }
for _, word := range words {
wg.Add(1)
go func(word string) {
time.Sleep(1 * time.Second)
defer wg.Done()
fmt.Println(word)
}(word)
}
// do concurrent things here
// blocks/waits for waitgroup
wg.Wait()
}
Korzystanie kanał
func main() {
words = []string{ "foo", "bar", "baz" }
done := make(chan bool)
defer close(done)
for _, word := range words {
go func(word string) {
time.Sleep(1 * time.Second)
fmt.Println(word)
done <- true
}(word)
}
// Do concurrent things here
// This blocks and waits for signal from channel
<-done
}
Zostałem poinformowany, że sync.WaitGroup
jest nieco bardziej wydajne, a ja h ave widziałem, że jest powszechnie używany. Jednak uważam, że kanały są bardziej idiomatyczne. Jaka jest prawdziwa zaleta korzystania z kanałów i/lub jaka może być sytuacja, gdy jest lepiej?
W drugim przykładzie synchronizacja jest nieprawidłowa. blokujesz, dopóki pierwszy goroutine nie wyśle na kanał, aż do ostatniego. –
Spójrz na: https://github.com/golang/go/wiki/MutexOrChannel#wait-group – molivier
@Not_a_Golfer z jakiegoś powodu, kiedy zmieniłem argument w funkcji goroutine na 'word' wypisuje wszystkich członków prawidłowo. – PieOhPah