Me familiarisant avec la concurrence, j'ai commencé à écrire un simple cli ping avec des appels concurrents (ignorons que je ne mesure pas vraiment les pings).
Le problème est que je ne peux pas fermer le canal correctement pour la boucle de portée tout en attendant que toutes les goroutines se terminent. Si je veux appeler simultanément la fonction ping, je ne peux pas la synchroniser avec les groupes d'attente, car j'atteindrai la ligne wg.Wait() avant la fin de toutes les goroutines.
Existe-t-il un moyen de maintenir les appels ping simultanés et de fermer le canal une fois qu'ils sont terminés, afin que la boucle de portée puisse se terminer ?
func main() {
domain := flag.String("domain", "google.com", "the domain u want to ping")
flag.Parse()
sum := 0
ch := make(chan int)
go start_pings(*domain, ch)
for elapsed := range ch {
fmt.Println("Part time: " + strconv.Itoa(elapsed))
sum += elapsed
}
avg := sum / 3
fmt.Println("Average: " + strconv.Itoa(avg))
}
func start_pings(domain string, ch chan int) {
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go ping(domain, ch, wg)
}
wg.Wait()
close(ch)
}
func ping(domain string, ch chan int, wg sync.WaitGroup) {
url := "http://" + domain
start := time.Now()
fmt.Println("Start pinging " + url + "...")
resp, err := http.Get(url)
elapsed := time.Now().Sub(start)
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
ch <- int(elapsed)
wg.Done()
}