To add to nos' answer, you can simulate that case (where "test2 <- true
" is run at the moment which is just between the first iteration and the second iteration") easily enough by making your first message reception (case <- test
) wait one second.
case <-test:
log.Println("test")
time.Sleep(1 * time.Second)
By the time the anonymous goroutine wakes up, main()
has already sent its two messages to the two buffered channel (buffer means non-blokcing for one message), and exited.
If main()
exits, everything else, including the goroutine which was busy sleeping, stops.
See play.golang.org: the output would be:
2009/11/10 23:00:00 test
You wouldn't have the time to see test2
.
In order to make sure your goroutine can process both message, you need:
main()
to wait for said goroutine to finish. That is where the sync
package comes into play, using (for instance, this isn't the only solution) a WaitGroup
directive.
var wg sync.WaitGroup
wg.Add(1)
go func() {
// Decrement the counter when the goroutine completes.
defer wg.Done()
...
}
... // end of main():
// Wait for goroutine to complete.
wg.Wait()
the goroutine to actually exit at some time (instead of being stuck in the for
loop forever). See "In Go, does a break statement break from a switch/select?"
loop: <==========
for {
select {
case <-test:
log.Println("test")
time.Sleep(1 * time.Second)
case <-test2:
log.Println("test2")
break loop <==========
}
}
See play.golang.org: the message test2
is sent while the goroutine is sleeping after test1
, but main()
will wait (wg.Wait()
), and the goroutine will have its chance to read and print test2
one second later.
The output is:
2009/11/10 23:00:00 test
2009/11/10 23:00:01 test2 // one second later