Go, passing data to channel

Issue

I have an issue. Here is example: https://play.golang.org/p/QSWY2INQuSE

func Avg(c chan string, wg *sync.WaitGroup) {
    defer wg.Done()
    c <- "test"
}

func main() {
    var wg sync.WaitGroup
    c := make(chan string)

    timer1 := time.NewTicker(5 * time.Second)

    for {
        select {
        case <-timer1.C:
            wg.Add(1)
            go Avg(c, &wg)
            wg.Wait()
        }
    }
    fmt.Println(<-c)
}

Why data does not reach fmt.Println(<-c)

Thank you!

Solution

Because you have an endless for, so the last fmt.Println() statement is never reached.

You have to break out of the loop if you want the last fmt.Println() statement to ever execute, for example:

loop:
    for {
        select {
        case <-timer1.C:
            wg.Add(1)
            go Avg(c, &wg)
            wg.Wait()
            break loop
        }
    }
    fmt.Println(<-c)

Note that you have to use a label, else the break would only break out of the select statement (and not from the for loop).

Also note that this alone won’t work, as the channel is unbuffered, and thus Avg() will be blocked forever, trying to send a value on c while noone is ever trying to receive from it.

This simple example can be made working if you create the channel to be buffered:

c := make(chan string, 1) // Buffer for 1 value

Now it works and prints (try it on the Go Playground):

test

Answered By – icza

Answer Checked By – Marilyn (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.