熟悉了并发性,因此开始编写一个简单的带有并发调用的ping cli(让我们忽略我并不是真正在测量ping).
问题是,我不能在等待所有大猩猩程序结束的同时,正确地关闭距离循环的通道. 如果我想并发调用ping函数,则无法将其与等待组同步,因为我将在所有Goroutine完成之前到达wg.Wait()行.
有没有办法让ping调用保持并发,并在它们完成后关闭通道,这样范围循环就可以退出?
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()
}