concurrency - sync.WaitGroup 不等待

标签 concurrency go

可能是我看不到明显的东西,我做错了什么:

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()
}

如果我删除 wg 并继续,我会正确收到每个 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()
 }

最佳答案

所有的 goroutines 都共享一个 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()
}

关于concurrency - sync.WaitGroup 不等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30579752/

相关文章:

java - 如何原子地替换非同步并发列表或数组

java - 将Java读锁升级为写锁,用于Map中的缓存

concurrency - 为什么我所谓的并行 go 程序不是并行的

Golang 如何在不旋转的情况下上传外部图像

go - 从具有不同代理设置的不同存储库构建

java - Thread.start() 和 Thread.run() 有什么区别?

linux - 如何执行具有并发和等待限制的多个命令?

java - ExecutorService.awaitTermination() 永远不会超时

go - goroutine 调用行之后的行是否比 goroutine 的第一行更早开始?

java - RSA OAEP , Golang 解密 , Java 加密