Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Incorrect output by goroutines

I am watching a lecture in which author build a status app using go routines which is behaving weirdly after sometime.

Here’s the code:

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

    c := make(chan string)

    for _, link := range links {
        go checkLink(link, c)
    }

    for l := range c {
        go func() {
            time.Sleep(5 * time.Second)
            checkLink(l, c)
        }()
    }
}

func checkLink(link string, c chan string) {
    _, err := http.Get(link)

    if err != nil {
        fmt.Println(link, "might be down!")
        c <- link
        return
    }
    fmt.Println(link, "is up!")
    c <- link
}

The output I get is:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

http://stackoverflow.com is up!

http://google.com is up!

http://facebook.com is up!

http://golang.org is up!

http://amazon.com is up!

http://amazon.com is up!

http://amazon.com is up!

http://amazon.com is up!

http://amazon.com is up!

http://amazon.com is up!

I don’t understand why the "amazon.com" keeps on repeating here?? Why is this happening after all the 5 links has been printed?

>Solution :

The issue lies in the closure capturing of the loop variable l. Since the goroutine is started inside a loop, all goroutines created by the loop share the same memory address for l. By the time the sleep is over and the goroutine is executed, the value of l has changed due to the loop iterating over the remaining links. Consequently, all goroutines end up checking the last link in the links slice, which is "http://amazon.com&quot;.
To fix this, you need to pass the loop variable l as an argument to the anonymous function inside the goroutine. Here’s an updated version of the code:

for l := range c {
    go func(link string) {
        time.Sleep(5 * time.Second)
        checkLink(link, c)
    }(l)
}

By passing l as an argument to the anonymous function, each goroutine will have its own copy of l, preserving the correct value for each iteration.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading