0Pricing
Go Academy · Lekcja

Wzorzec puli pracowników

Tworzenie puli pracowników goroutines o stałym rozmiarze

Wzorzec puli pracowników to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 4 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.

Czym jest pula pracowników?

Pula pracowników z wyprzedzeniem tworzy stałą liczbę gorutyn, które przetwarzają zadania ze współdzielonej kolejki. Ogranicza to współbieżność i zapobiega wyczerpaniu zasobów wskutek nieograniczonego tworzenia gorutyn.

Podstawowa implementacja

Należy utworzyć kanał jobs oraz N gorutyn, z których każda odczytuje dane z tego kanału:

func workerPool(n int, jobs <-chan Job, results chan<- Result) {
    var wg sync.WaitGroup
    for i := 0; i < n; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            for job := range jobs {
                results <- process(job)
            }
        }()
    }
    wg.Wait()
    close(results)
}

Wysyłanie zadań

Należy wysłać wszystkie zadania do kanału, a następnie go zamknąć. Pracownicy przetworzą wszystkie zadania i zakończą swoje pętle range po zamknięciu kanału.

jobs := make(chan Job, 100)
for _, j := range allJobs {
    jobs <- j
}
close(jobs) // signals workers to stop after draining

Zbieranie wyników

Należy odczytywać wyniki równolegle z wysyłaniem zadań. Pula powinna działać w osobnej gorutynie, aby zbieranie wyników nie doprowadziło do zakleszczenia podczas przekazywania zadań.

results := make(chan Result, 100)
go workerPool(5, jobs, results)
for r := range results {
    collect(r)
}

Dostosowywanie rozmiaru puli

W przypadku pracy obciążającej procesor należy ustawić rozmiar puli na runtime.NumCPU(). W przypadku pracy związanej z operacjami wejścia-wyjścia większy mnożnik (np. 10×) pozwala lepiej wykorzystać czas oczekiwania. Należy wykonać profilowanie, aby znaleźć optymalną wartość.

n := runtime.NumCPU()
if ioHeavy { n = runtime.NumCPU() * 10 }

Dodawanie anulowania za pomocą kontekstu

Należy przekazać kontekst pracownikom, aby mogli wcześniej zakończyć działanie po anulowaniu:

for {
    select {
    case job, ok := <-jobs:
        if !ok { return }
        results <- process(ctx, job)
    case <-ctx.Done():
        return
    }
}

Alternatywa w postaci semafora

Zamiast stałej puli gorutyn można użyć buforowanego kanału jako semafora ograniczającego liczbę gorutyn działających współbieżnie, zachowując jednocześnie możliwość uruchamiania jednej gorutyny dla każdego zadania.

sem := make(chan struct{}, 10)
for _, job := range jobs {
    sem <- struct{}{}
    go func(j Job) {
        defer func() { <-sem }()
        process(j)
    }(job)
}

Obsługa błędów

Należy zwracać błędy razem z wynikami, używając struktury wyniku. Po pierwszym błędzie należy anulować kontekst albo zebrać wszystkie błędy i przedstawić je w końcowym raporcie.

type Result struct{ Val int; Err error }

Dynamiczne dopasowywanie rozmiaru puli

W przypadku pul adaptacyjnych należy użyć golang.org/x/sync/semaphore, który umożliwia pozyskiwanie i zwalnianie ważonego zasobu oraz obsługuje dynamiczne limity współbieżności.

Pula pracowników a errgroup

golang.org/x/sync/errgroup udostępnia prostszy interfejs do uruchamiania N gorutyn i zbierania pierwszego błędu. Puli należy użyć, gdy potrzebny jest stały zestaw wielokrotnego użytku pracowników.

Kontrolowane zamykanie

Należy zamknąć kanał jobs, aby zasygnalizować pracownikom zakończenie pracy. Po zakończeniu WaitGroup należy zamknąć kanał wyników. Wszystkie oczekujące wysłania zadań muszą nastąpić przed close(jobs).

Szybkie sprawdzenie

W jaki sposób pula pracowników sygnalizuje pracownikom zakończenie przetwarzania?

Podsumowanie: pula pracowników

Najważniejsze informacje:

  • Stała liczba N gorutyn odczytuje dane z jednego kanału jobs
  • Zamknięcie kanału jobs sygnalizuje pracownikom zakończenie pracy
  • WaitGroup śledzi zakończenie pracy; po jej zakończeniu należy zamknąć kanał wyników
  • Praca obciążająca procesor: rozmiar puli ≈ NumCPU; praca związana z operacjami wejścia-wyjścia: większy

Często zadawane pytania

Czy lekcja „Wzorzec puli pracowników” jest bezpłatna?

Tak — pełny tekst „Wzorzec puli pracowników” 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 „Wzorzec puli pracowników”?

Tworzenie puli pracowników goroutines o stałym rozmiarze Ć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 4 z 4.

Ile czasu zajmuje lekcja „Wzorzec puli pracowników”?

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. Instrukcja select
  2. Limity czasu i tickery
  3. Wzorce fan-in i fan-out
  4. Wzorzec puli pracowników
← Powrót do Go Academy