小编典典

遍历通道时关闭通道的最佳时间

go

我正在玩Golang,我创建了这个小应用程序,使用goroutines进行了多个并发的api调用。

当应用程序运行时,调用完成后,该应用程序将卡住,这是有道理的,因为由于通道未关闭,无法退出 范围c 循环。

我不确定在哪种情况下可以更好地关闭该通道。

package main

import "fmt"
import "net/http"

func main() {
    links := []string{
        "https://github.com/fabpot",
        "https://github.com/andrew",
        "https://github.com/taylorotwell",
        "https://github.com/egoist",
        "https://github.com/HugoGiraudel",
    }

    checkUrls(links)
}

func checkUrls(urls []string) {
    c := make(chan string)

    for _, link := range urls {
        go checkUrl(link, c)
    }

    for msg := range c {
        fmt.Println(msg)
    }

    close(c) //this won't get hit
}

func checkUrl(url string, c chan string) {
    _, err := http.Get(url)

    if err != nil {
        c <- "We could not reach:" + url
    } else {
        c <- "Success reaching the website:" + url
    }
}

阅读 288

收藏
2020-07-02

共1个答案

小编典典

当没有更多值要发送时,您将关闭通道,因此在这种情况下,所有checkUrlgoroutine已完成。

var wg sync.WaitGroup

func checkUrls(urls []string) {
    c := make(chan string)

    for _, link := range urls {
        wg.Add(1)
        go checkUrl(link, c)
    }

    go func() {
        wg.Wait()
        close(c)
    }()

    for msg := range c {
        fmt.Println(msg)
    }
}

func checkUrl(url string, c chan string) {
    defer wg.Done()
    _, err := http.Get(url)

    if err != nil {
        c <- "We could not reach:" + url
    } else {
        c <- "Success reaching the website:" + url
    }
}

(请注意,errorfrom
http.Get仅将反映连接和协议错误。如果您也期望这些错误,则它不会包含http服务器错误,您必须了解如何检查路径,而不仅仅是主机。)

2020-07-02