我正在学习使用,我的第一个项目之一是一个简单的ping脚本。基本上我想ping一堆网址,并在每个人的响应等待XXX秒数然后再次ping。下面是删节代码:在goroutines内部启动goroutines是否可以接受?
func main() {
// read our text file of urls
f, err := ioutil.ReadFile(urlFile)
if err != nil {
log.Print(err)
}
urlStrings := []string{}
urlStrings = strings.Split(string(f), "\n")
for _, v := range urlStrings {
go ping(v)
}
// output logs to the terminal
// channel is global
for i := range c {
fmt.Println(i)
}
}
func ping(url string) {
// for our lag timer
start := time.Now()
// make our request
_, err := http.Get(url)
if err != nil {
msg := url + " Error:" + err.Error()
fmt.Println(msg)
c <- msg
reportError(msg)
} else {
lag := time.Since(start)
var msg string
// running slow
if lag > lagThreshold*time.Second {
msg = url + " lag: " + lag.String()
reportError(msg)
}
msg = url + ", lag: " + lag.String()
c <- msg
}
time.Sleep(pingInterval * time.Second)
go ping(url) // is this acceptable?
}
在我的Get请求我以前呼吁推迟res.Body.Close(),但是这是panicing后的应用程序运行一段时间。我认为延迟无法在响应中调用Close(),直到goroutine被垃圾收集并且res不再存在。
这让我想到如果通过调用goroutine内部的goroutine是最佳做法,或者如果我导致函数永不退出,那么只有在goroutine被垃圾收集后才会调用延迟。
从其他goroutines产生goroutines应该没有任何问题,但是有什么理由不在这种情况下使用循环吗? – 2013-04-29 21:28:12
@JamesHenstridge I在程序循环中没有这样做,所以我不必在每次请求返回之前等待每个请求返回。我试图使用并发性,因此每个ping周期都是基于它自己的滞后时间而独立的。 – ARolek 2013-04-29 22:52:50
我指的是'ping()'goroutine在退出前产生另一个goroutine的部分。如果你在'ping()'中放置一个循环,你会得到同样的效果。 – 2013-04-29 23:26:21