Miha Zoubek
Miha Zoubek

Reputation: 65

Go, passing data to channel

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!

Upvotes: 2

Views: 277

Answers (1)

icza
icza

Reputation: 418465

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

Upvotes: 5

Related Questions