为什么 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


叮当猫咪
浏览 132回答 2
2回答

慕码人8056858

你启动了 5 个 goroutine,但只读取了一个的输入。此外,您不会等待 goroutines 结束。// If there are only 5 goroutines unconditionally, you don't need the wgfor i := 1; i <= 5; i++ {&nbsp; &nbsp; &nbsp; &nbsp; go worker("www"+strconv.Itoa(i),&nbsp; names)}for i:=1;i<=5;i++ {&nbsp; &nbsp;fmt.Println(<-names)}然而,如果你不知道你在等待多少个 goroutine,那么等待组是必要的。for i := 1; i <= 5; i++ {&nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; go worker("www"+strconv.Itoa(i), &wg, names)}// Read from the channel until it is closeddone:=make(chan struct{})go func() {&nbsp; &nbsp;for x:=range names {&nbsp; &nbsp; &nbsp;fmt.Println(x)&nbsp; &nbsp; }&nbsp; &nbsp; // Signal that println is completed&nbsp; &nbsp; close(done)}()// Wait for goroutines to endwg.Wait()// Close the channel to terminate the reader goroutineclose(names)// Wait until println completes<-done

慕少森

您正在启动 5 个 goroutine,但仅从频道读取names一次。fmt.Println(<-names)一旦第一个通道读取完成,就main()退出。这意味着一切都在有时间执行之前停止。要了解有关通道的更多信息,请参阅Dave Cheney的“轻松实现并发”&nbsp;:如果您必须等待操作的结果,那么您自己做会更容易。以您获得它们的相反顺序释放锁和信号量。通道不是文件或套接字之类的资源,您无需关闭它们即可释放它们。准备好使用信号量时获取信号量。避免混合匿名函数和 goroutines在你启动一个 goroutine 之前,总是知道它何时以及如何停止
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go