簡體   English   中英

為什么 goroutine 只作為等待組的一部分運行一次

[英]Why does the goroutine only run once as part of a waitgroup

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 個結果,但只有一個執行並且過程結束。 有什么我想念的嗎? go 的新功能。 端點是返回 json 的通用 API

你啟動了 5 個 goroutine,但只讀取了一個的輸入。 此外,您不會等待 goroutines 結束。

// If there are only 5 goroutines unconditionally, you don't need the wg
for i := 1; i <= 5; i++ {
        go worker("www"+strconv.Itoa(i),  names)
}
for i:=1;i<=5;i++ {
   fmt.Println(<-names)
}

然而,如果你不知道你在等待多少個 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

您正在啟動 5 個 goroutine,但僅從names通道讀取一次。

fmt.Println(<-names)

一旦第一個通道讀取完成, main()就會退出。
這意味着一切都在有時間執行之前停止。

要了解有關通道的更多信息,請參閱Dave Cheney的“輕松實現並發”:

  • 如果您必須等待操作的結果,那么您自己做會更容易。
  • 以您獲得它們的相反順序釋放鎖和信號量。
  • 通道不是文件或 sockets 之類的資源,您無需關閉它們即可釋放它們。
  • 准備好使用信號量時獲取信號量。
  • 避免混合匿名函數和 goroutines
  • 在你啟動一個 goroutine 之前,總是知道它何時以及如何停止

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM