登录
首页 >  Golang >  Go问答

为什么这个循环永远不会结束?

来源:stackoverflow

时间:2024-03-25 16:27:23 189浏览 收藏

在给定的代码中,一个无限循环被触发,因为通道 `c` 永远不会关闭。在 Go 语言中,只有当通道关闭时,`range` 语句才会退出,而该代码中没有关闭通道的操作。为了解决这个问题,需要在适当的条件下关闭通道,例如当通道中已接收了足够数量的元素时。

问题内容

有以下代码,使用该代码会导致无限循环。来自通道的值是正确的,变量 sum 的值也是正确的。所有 goroutine 最终都没有错误。

func responseHandler(w http.ResponseWriter, r *http.Request) {
    var c = make(chan string)
    for i := 0; i < 100; i++ {
        url := fmt.Sprintf("someurl/page%v/etc", i)
        go parse(url, i, c)
        if i%5 == 0 {
            time.Sleep(1000 * time.Millisecond)
        }
    }
    for range c {
        sum = append(sum, <-c)
    }
    fmt.Println("Exit from channel wait")
    fmt.Fprintln(w, sum)
}

func parse(url string, num int, c chan string) {
    response, err1 := http.Get(url)
    if err1 != nil {
        log.Fatal(err1)
    }
    defer response.Body.Close()

    if response.StatusCode != 200 {
        log.Fatalf("status code error: %d %s", response.StatusCode, 
response.Status)
    }

    res, err := DecodeHTMLBody(response.Body, "windows-1251")

    doc, err := goquery.NewDocumentFromReader(res)
    if err != nil {
        log.Fatal(err)
    }

    doc.Find(".b-advItem__content").Each(func(i int, s *goquery.Selection) {
        title := strings.TrimSpace(s.Find(".someclass").Text())
        price := strings.TrimSpace(s.Find(".someclass").Text())
        formatPrice := parsePrice(price)
        c <- fmt.Sprintf("output %d: %s:%s\n", i, title, formatPrice)
    })
    fmt.Printf("Channel %d - exit\n", num)

总和 - 全局 [] 字符串。


解决方案


仅当通道关闭时,通道上的 range 语句才会退出(好吧,想一想:否则 range 如何检测到没有更多数据可供获取?),并且代码中没有任何内容会关闭通道。

func responseHandler(w http.ResponseWriter, r *http.Request) {
   ...
   for range c {
    sum = append(sum, <-c)
    if len(aa) == 100 {
        close(c)
   }
    fmt.Fprintln(w, sum)
}

func parse(...){
     ...
     aa = append(aa, num)
}

添加这样的检查可以让你正确退出循环

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>