为什么goroutine在等待组中只能运行一次

时间:2020-08-19 04:21:40

标签: go goroutine

func check(name string) string {
    resp, err := http.Get(endpoint + name)
    if err != nil {
        panic(err)
    }

    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)

    if err != nil {
        panic(err)
    }

    return string(body)

}

func worker(name string, wg *sync.WaitGroup, names chan string) {
    defer wg.Done()
    var a = check(name)
    names <- a
}

func main() {
    names := make(chan string)
    var wg sync.WaitGroup

    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go worker("www"+strconv.Itoa(i), &wg, names)
    }
    fmt.Println(<-names)
}

预期结果将是5个结果,但是只有一个执行,并且过程结束。 我有什么想念的吗?新的去。 端点是返回json

的通用API

2 个答案:

答案 0 :(得分:3)

您启动了5个goroutine,但是仅读取了一个输入。另外,您不必等待goroutine结束。

for i := 1; i <= 5; i++ {
      wg.Add(1)
      go worker("www"+strconv.Itoa(i), &wg, names)
}
// Read from the channel until it is closed
done:=make(chan struct{})
go func() {
   for x:=range names {
     fmt.Println(x)
    }
    // Signal that println is completed
    close(done)
}()

// Wait for goroutines to end
wg.Wait()
// Close the channel to terminate the reader goroutine
close(names)
// Wait until println completes
<-done

但是,如果您不知道正在等待多少个goroutine,则需要等待组。

        HStack {
            Text("Test")
                .font(.largeTitle)
                .fontWeight(.bold)
                .multilineTextAlignment(.leading)
            Spacer()
        }
        .frame(width: 480, height: 160, alignment: .top)   // << here !!

答案 1 :(得分:2)

您正在启动5个goroutine,但仅从names通道读取一次。

fmt.Println(<-names)

第一个频道读取完成后,main()退出。
这意味着一切都在有时间执行之前就停止了。

要了解有关渠道的更多信息,请参见Concurrency made easy中的“ Dave Cheney”:

  • 如果您必须等待操作结果,则自己动手即可。
  • 以与获取锁和信号灯相反的顺序释放锁和信号灯。
  • 频道不是文件或套接字之类的资源,您无需关闭即可释放它们。
  • 准备使用信号灯时要获取它们。
  • 避免混合使用匿名函数和goroutines
  • 启动goroutine之前,请始终知道它将何时,如何停止