任何更好的方式来跟踪goroutine的回应?
问题描述:
我试图让我的头围绕goroutines。我创建了一个简单的程序,可以跨多个搜索引擎并行执行相同的搜索。为了跟踪答复的数量,我计算了我收到的电话号码。虽然这似乎有点业余。任何更好的方式来跟踪goroutine的回应?
当我从下面的代码中收到所有goroutine的响应时,是否有更好的方式知道?
package main
import (
"fmt"
"net/http"
"log"
)
type Query struct {
url string
status string
}
func search (url string, out chan Query) {
fmt.Printf("Fetching URL %s\n", url)
resp, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out <- Query{url, resp.Status}
}
func main() {
searchTerm := "carrot"
fmt.Println("Hello world! Searching for ", searchTerm)
searchEngines := []string{
"http://www.bing.co.uk/?q=",
"http://www.google.co.uk/?q=",
"http://www.yahoo.co.uk/?q="}
out := make(chan Query)
for i := 0; i < len(searchEngines); i++ {
go search(searchEngines[i] + searchTerm, out)
}
progress := 0
for {
// is there a better way of doing this step?
if progress >= len(searchEngines) {
break
}
fmt.Println("Polling...")
query := <-out
fmt.Printf("Status from %s was %s\n", query.url, query.status)
progress++
}
}
答
请使用sync.WaitGroup
,有在pkg doc
searchEngines := []string{
"http://www.bing.co.uk/?q=",
"http://www.google.co.uk/?q=",
"http://www.yahoo.co.uk/?q="}
var wg sync.WaitGroup
out := make(chan Query)
for i := 0; i < len(searchEngines); i++ {
wg.Add(1)
go func (url string) {
defer wg.Done()
fmt.Printf("Fetching URL %s\n", url)
resp, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out <- Query{url, resp.Status}
}(searchEngines[i] + searchTerm)
}
wg.Wait()
为例,用户可以简化环路二号位,混帐摆脱进度变量,做同样的事情,第一个for循环:'for i:= 0;我
monoxygen
2013-02-23 09:16:13
噢,谢谢。出于某种原因,我不感谢它的工作。 – 2013-02-23 09:31:20
你也可以倒数到零而不是数起来。在等待一组goroutines完成时,这对我来说似乎更加自然。这与滚动你自己的等待组无异,并且很容易理解(在我看来,根本不是'业余')。 – 2013-02-24 08:58:04