ryan
ryan

Reputation: 1084

Trying to understand go func with WaitGroup

I have the following code https://play.golang.org/p/9jPlypO4d-

package main
import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup
    wg.Add(1)
    c := make(chan int)
    go func() {
            defer wg.Done()
            for {
                    if <-c == -1 {
                            fmt.Print(":")
                            return
                    }

                    fmt.Print(".")
                    time.Sleep(time.Second)
            }

    }()

    c <- 0
    time.Sleep(time.Second * 5)
    c <- -1
    wg.Wait()
}

I wonder why there is only one . printed? Shouldn't it be like 4 or 5?

Upvotes: 0

Views: 136

Answers (1)

dave
dave

Reputation: 64657

if <-c == -1 will block until there is something in the channel. So, the first value is 0, it gets it, prints out a ., sleeps one second (while outside the goroutine it is sleeping 5 seconds), then it blocks until it gets the next value. And then it returns.

The only way to read a channel without blocking (that I know of) is to use a select statement with a default case.

go func() {
    defer wg.Done()
    for {
        select {
        case x, ok := <-c:
            if ok && x == -1 {
                fmt.Print(":")
                return
            }
        default:
            fmt.Print(".")
        }

        time.Sleep(time.Second)
    }

}()

https://play.golang.org/p/nOG_hfih4D

Upvotes: 3

Related Questions