gochannel

Why read channel with go fmt.Println(<-c) doesnt work?


package main

import "fmt"

func main() {
    c := make(chan int)
    go fmt.Println(<-c)
    c <- 32
}

I have a goroutine that is blocked waiting for a value to a channel and have a write to a channel in the main goroutine. Why is the deadlock happening?

It seems to me that everything should be working, but a deadlock is occurring


Solution

  • The issue here is that the argument to fmt.Println is evaluated before the new goroutine is started up, not after. See the page on A Tour of Go. In other words, the code you have is (mostly) equivalent to doing the following:

    val := <-c
    go fmt.Println(val)
    

    This causes the main thread to deadlock because it is waiting for c to produce a value to pass into fmt.Println on the main goroutine. Since this keeps the goroutine busy, it never reaches the later line where you actually send a value on the channel.

    Try this instead:

    go func() { fmt.Println(<-c) }()
    

    Here, the execution of the function is handed off to a separate goroutine before <-c is evaluated. This allows the main goroutine to continue down until it hits c <- 32 to provide a value for the channel.