0Pricing
Go Academy · Lekcja

sync.WaitGroup

Oczekiwanie na zakończenie grupy goroutines

sync.WaitGroup to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Go Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Go Academy zawiera 4 lekcji w sumie.

Przeznaczenie

sync.WaitGroup czeka na zakończenie zbioru gorutyn. Główna gorutyna wywołuje Add, aby ustawić licznik, każda gorutyna wywołuje Done po zakończeniu, a Wait blokuje wykonanie do momentu, gdy licznik osiągnie zero.

Podstawowe użycie

Wywołuj Add przed uruchomieniem każdej gorutyny, Done na końcu każdej gorutyny (za pomocą defer), a Wait po uruchomieniu wszystkich gorutyn.

var wg sync.WaitGroup
for _, item := range items {
    wg.Add(1)
    go func(v Item) {
        defer wg.Done()
        process(v)
    }(item)
}
wg.Wait()

Add musi nastąpić przed uruchomieniem gorutyny

Wywołuj wg.Add(1) przed go func(), nigdy wewnątrz gorutyny. W przeciwnym razie Wait może zwrócić wynik, zanim gorutyna zarejestruje swoje uruchomienie.

Częsty błąd: przechwytywanie zmiennej pętli

Przekazuj zmienną pętli jako argument funkcji gorutyny, a nie za pośrednictwem domknięcia, aby uniknąć współdzielenia tej samej zmiennej przez wszystkie gorutyny.

for _, v := range items {
    wg.Add(1)
    go func(item Item) { // correct: copy
        defer wg.Done()
        process(item)
    }(v)
}

Ponowne używanie WaitGroup

WaitGroup można użyć ponownie po powrocie z Wait, ale tylko wtedy, gdy wszystkie wcześniejsze wywołania Done dobiegły końca. Nie używaj go ponownie równocześnie z trwającymi wywołaniami Done.

WaitGroup i wyniki

WaitGroup nie zbiera wyników — połącz go z kanałem albo z wycinkiem (chronionym za pomocą mutex), aby gromadzić dane wyjściowe z gorutyn.

results := make([]Result, len(items))
for i, item := range items {
    wg.Add(1)
    go func(idx int, v Item) {
        defer wg.Done()
        results[idx] = process(v)
    }(i, item)
}
wg.Wait()

Add z licznikiem grupowym

Możesz przekazać całkowitą liczbę do pojedynczego wywołania Add przed pętlą, co jest nieco wydajniejsze niż wywoływanie Add osobno dla każdej gorutyny.

wg.Add(len(items))
for _, item := range items {
    go func(v Item) { defer wg.Done(); process(v) }(item)
}

Nie kopiuj WaitGroup

Podobnie jak Mutex, WaitGroup nie może być kopiowany po pierwszym użyciu. Przekazuj go przez wskaźnik albo osadzaj w strukturze przekazywanej przez wskaźnik.

WaitGroup a errgroup

golang.org/x/sync/errgroup opakowuje WaitGroup i dodaje propagowanie błędów. Preferuj errgroup, gdy błąd dowolnej gorutyny powinien zatrzymać pozostałe.

Łączenie z context

Użyj errgroup.WithContext, aby uzyskać zarówno semantykę WaitGroup, jak i kontekst anulowany po pierwszym błędzie, co pozwala poprawnie zatrzymać wszystkie gorutyny.

g, ctx := errgroup.WithContext(context.Background())
g.Go(func() error { return doWork(ctx) })
if err := g.Wait(); err != nil { log.Fatal(err) }

Wartość zerowa jest gotowa do użycia

Wartość zerowa sync.WaitGroup jest gotowa do użycia — konstruktor nie jest potrzebny. Wystarczy zadeklarować obiekt i wywołać Add.

Szybki test

Co się stanie, jeśli wywołasz wg.Add(1) wewnątrz gorutyny zamiast przed jej uruchomieniem?

Podsumowanie: sync.WaitGroup

Najważniejsze informacje:

  • Wywołuj Add przed uruchomieniem gorutyny, a Done za pomocą defer wewnątrz gorutyny
  • Wait blokuje wykonanie do momentu, gdy licznik osiągnie zero
  • Nigdy nie kopiuj WaitGroup i nigdy nie wywołuj Add wewnątrz gorutyny
  • Używaj errgroup do propagowania błędów

Często zadawane pytania

Czy lekcja „sync.WaitGroup” jest bezpłatna?

Tak — pełny tekst „sync.WaitGroup” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Go Academy, przejdź na CoddyKit PRO. Kurs Go Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „sync.WaitGroup”?

Oczekiwanie na zakończenie grupy goroutines Ćwiczysz Go Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Go Academy?

Nie wymagamy żadnego doświadczenia. Go Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „sync.WaitGroup”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Go Academy?

Tak. Każda lekcja Go Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. sync.Mutex i sync.RWMutex
  2. sync.WaitGroup
  3. sync.Once i sync.Map
  4. Detektor wyścigów i bezpieczne wzorce
← Powrót do Go Academy