我正在玩 Golang,我创建了这个小应用程序来使用 goroutines 进行多个并发 api 调用。
虽然应用程序正常运行,但在调用完成后,应用程序会卡住,这是有道理的,因为它无法退出 range c 循环,因为 channel 未关闭。
我不确定在这种模式下哪里可以更好地关闭 channel 。
package main
import "fmt"
import "net/http"
func main() {
links := []string{
"https://github.com/fabpot",
"https://github.com/andrew",
"https://github.com/taylorotwell",
"https://github.com/egoist",
"https://github.com/HugoGiraudel",
}
checkUrls(links)
}
func checkUrls(urls []string) {
c := make(chan string)
for _, link := range urls {
go checkUrl(link, c)
}
for msg := range c {
fmt.Println(msg)
}
close(c) //this won't get hit
}
func checkUrl(url string, c chan string) {
_, err := http.Get(url)
if err != nil {
c <- "We could not reach:" + url
} else {
c <- "Success reaching the website:" + url
}
}
最佳答案
当没有更多值要发送时,您将关闭一个 channel ,因此在本例中,它是在所有 checkUrl
goroutines 完成时。
var wg sync.WaitGroup
func checkUrls(urls []string) {
c := make(chan string)
for _, link := range urls {
wg.Add(1)
go checkUrl(link, c)
}
go func() {
wg.Wait()
close(c)
}()
for msg := range c {
fmt.Println(msg)
}
}
func checkUrl(url string, c chan string) {
defer wg.Done()
_, err := http.Get(url)
if err != nil {
c <- "We could not reach:" + url
} else {
c <- "Success reaching the website:" + url
}
}
(请注意,来自 http.Get
的 error
只会反射(reflect)连接和协议(protocol)错误。如果您期望它不会包含 http 服务器错误还有那些,你必须看到你是如何检查路径而不仅仅是主机的。)
关于go - 迭代 channel 时关闭 channel 的最佳时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56603716/