Ce face sync.WaitGroup.Go
wg.Go(f) face trei lucruri deodată: wg.Add(1), pornește f cu go și apelează wg.Done() când f se termină. Codul devine mai scurt și nu mai poți uita Add sau Done.
Funcția f nu primește argumente și nu returnează nimic; datele le iei din variabilele din jur (închidere). Din Go 1.22 fiecare iterație a buclei for are variabilele ei, deci i și f din buclă pot fi folosite direct. Documentația cere ca f să nu se oprească cu panică.
Parametri
| Parametru | Descriere |
|---|---|
f |
Funcția de rulat în goroutine-ul nou, de forma func(). |
Ce returnează
Nimic.
Exemple
Exemplul 1: Verificarea mai multor site-uri
package main
import (
"fmt"
"sync"
"time"
)
func verifica(site string) string {
time.Sleep(10 * time.Millisecond)
if site == "vechi.example" {
return "nu răspunde"
}
return "ok"
}
func main() {
site := []string{"dexblog.ro", "vechi.example", "go.dev"}
stare := make([]string, len(site))
var wg sync.WaitGroup
for i, s := range site {
wg.Go(func() {
stare[i] = verifica(s)
})
}
wg.Wait()
for i, s := range site {
fmt.Printf("%-14s %s\n", s, stare[i])
}
}
Rezultat
dexblog.ro ok
vechi.example nu răspunde
go.dev ok
Exemplul 2: Go împreună cu un mutex
Numărăm cuvintele din mai multe texte în paralel într-un singur map, protejat de mutex.
package main
import (
"fmt"
"strings"
"sync"
)
func main() {
texte := []string{
"ana are mere",
"mere și pere la piață",
"ana vinde pere",
}
var (
wg sync.WaitGroup
mu sync.Mutex
frecvente = map[string]int{}
)
for _, t := range texte {
wg.Go(func() {
for _, cuv := range strings.Fields(t) {
mu.Lock()
frecvente[cuv]++
mu.Unlock()
}
})
}
wg.Wait()
fmt.Println(frecvente)
}
Rezultat
map[ana:2 are:1 la:1 mere:2 pere:2 piață:1 vinde:1 și:1]
Greșeli frecvente
- Scrii
wg.Go(lucru(x)): asta apeleazălucruimediat, în goroutine-ul curent. Scriewg.Go(func() { lucru(x) }). - Combini
wg.Gocuwg.Add(1)saudefer wg.Done()pentru aceeași sarcină; contorul se strică.Gole face singur.
Comenzi înrudite
sync.WaitGroup: Așteaptă ca un grup de goroutine să termine: Add mărește contorul, Done îl scade, Wait blochează până ajunge la zero.sync.Mutex: Lacăt de excludere reciprocă: doar un goroutine pe rând poate rula codul dintre Lock() și Unlock().