Search code examples
gochannelgoroutine

Golang channel do not close


I dont get it, why the channel is not closing. I use Waitgroup to explicitly wait and close the channel after it...but th programm isnt exiting. Thank you for your help

( https://play.golang.org/p/lto2DytWH13 )

package main

import (
    "fmt"
    "net/http"
    "sync"
)

var wg sync.WaitGroup

func main() {
    links := []string{
        "http://google.com",
        "http://facebook.com",
        "http://stackoverflow.com",
        "http://golang.org",
        "http://amazon.com",
    }
    wg.Add(len(links))
    c := make(chan string)

    for _, link := range links {
        go checkLink(link, c, &wg)
    }
    wg.Wait()
    close(c)
    for u := range c {
        fmt.Println(u)
    }
}

func checkLink(link string, c chan string, wg *sync.WaitGroup) {
    _, err := http.Get(link)
    if err != nil {
        fmt.Println(link, "might be down!")
        c <- link
        return
    }

    fmt.Println(link, "is up!")
    c <- link
    wg.Done()
}

Solution

  • Here are the problems with your program:

    • When a goroutine successfully reads the link, it prints the is up! message, and starts waiting to write the channel. The main goroutine waits for all goroutines to exit, then closes the channel and reads from it. At this point, all goroutines are asleep.
    • You are closing the channel, and reading from it. That will immediately return the zero value, i.e. ""
    • Your goroutines will return without calling wg.Done() if reading from the link fails.

    To fix, use:

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