英文:
sync.WaitGroup doesnt waits
问题
也许我没有看到明显的问题,我做错了什么:
func printSize(listOfUrls []string) {
var wg sync.WaitGroup
wg.Add(len(listOfUrls))
for _, myurl := range listOfUrls {
go func() {
body := getUrlBody(myurl)
fmt.Println(len(body))
wg.Done()
}()
}
wg.Wait()
}
如果我移除 wg
和 go
,我可以正确地接收到每个 URL 正文的大小。但是按照上面的方式,它几乎立即打印出零。getUrlBody()
有时需要执行几分钟。
回答评论:我也尝试了这种方式,为了确保,它表现出相同的行为。
我发现错误出现在 getUrlBody
和 main()
函数中...
func printSize(listOfUrls []string) {
var wg sync.WaitGroup
wg.Add(len(listOfUrls))
for _, myurl := range listOfUrls {
go f(myurl, &wg)
}
wg.Wait()
}
func f(myurl string, wg *sync.WaitGroup) {
body := getUrlBody(myurl)
fmt.Println(len(body))
wg.Done()
}
英文:
May be I can not see obvious thing, what am I doing wrong:
func printSize (listOfUrls []string){
var wg sync.WaitGroup
wg.Add(len(listOfUrl))
for _, myurl := range(listOfUrls){
go func(){
body := getUrlBody(myurl)
fmt.Println(len(body))
wg.Done()
}()
}
wg.Wait()
}
If I remove wg and go, I receive the size of each url body correctly. If I do it as in above, it prints zeroes almost instantly. The getUrlBody() takes time to execute sometimes minutes.
Answering comment: I also tried it this way, to be sure, and it demonstrate same behaviour.
I found the error was in getUrlBody and main() function...
func printSize(listOfUrls []string) {
var wg sync.WaitGroup
wg.Add(len(listOfUrls))
for _, myurl := range listOfUrls {
go f(myurl, &wg)
}
wg.Wait()
}
func f(myurl string, wg *sync.WaitGroup) {
body := getUrlBody(myurl)
fmt.Println(len(body))
wg.Done()
}
答案1
得分: 2
所有的goroutine都共享单个myurl
变量。请参阅https://golang.org/doc/faq#closures_and_goroutines获取更多信息。
将代码更改为:
func f(listOfUrls []string){
var wg sync.WaitGroup
wg.Add(len(listOfUrl))
for _, myurl := range(listOfUrls){
go func(myurl string){
body := getUrlBody(myurl)
fmt.Println(len(body))
wg.Done()
}(myurl)
}
wg.Wait()
}
或者
func f(listOfUrls []string){
var wg sync.WaitGroup
wg.Add(len(listOfUrl))
for _, myurl := range(listOfUrls){
myurl := myurl
go func(){
body := getUrlBody(myurl)
fmt.Println(len(body))
wg.Done()
}()
}
wg.Wait()
}
英文:
All of the goroutines are sharing the single myurl
variable. See https://golang.org/doc/faq#closures_and_goroutines for more information.
Change the code to:
func f(listOfUrls []string){
var wg sync.WaitGroup
wg.Add(len(listOfUrl))
for _, myurl := range(listOfUrls){
go func(myurl string){
body := getUrlBody(myurl)
fmt.Println(len(body))
wg.Done()
}(myurl)
}
wg.Wait()
}
or
func f(listOfUrls []string){
var wg sync.WaitGroup
wg.Add(len(listOfUrl))
for _, myurl := range(listOfUrls){
myurl := myurl
go func(){
body := getUrlBody(myurl)
fmt.Println(len(body))
wg.Done()
}()
}
wg.Wait()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论