Why is only one channel value displayed?

I found this code:

package main
 
import "fmt"
 
func greet(c chan string) {
    fmt.Println(<-c) // for John
    fmt.Println(<-c) // for Mike
}
 
func main() {
 
    c := make(chan string)
 
    go greet(c)
    c <- "John"
 
    c <- "Mike"
 
    //close(c) // closing channel
 
}

In the output there is only “John” without “Mike”. And if I write something like c ← “Adam” with the third fmt.Println(<-c) in the greet function, in the output there will be “John”, “Mike” and “Adam”. Why is it happening?

This is happening because main() is exiting before both fmt.Println calls can complete. Just to illustrate this, add a time.Sleep(20 * time.Millisecond) or some arbitrary time after c <- "Mike". This will give greet ample time to print all values.

When you’re dealing with concurrency, you need something to sync/block until your concurrent code has time to execute. Check sync.WaitGroup out for an example of concurrent tasks where the main thread blocks until all have completed. Other useful links:

The channel synchronization pattern above of passing in done chan bool is pretty standard and I’ve seen that plenty of places in the wild.

3 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.