Reputation: 1084
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
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