I'm sure that there is a simple explanation to this trivial situation, but I'm new to the go
concurrency model.
when I run this example
package main
import "fmt"
func main() {
c := make(chan int)
c <- 1
fmt.Println(<-c)
}
I get this error :
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/home/tarrsalah/src/go/src/github.com/tarrsalah/tour.golang.org/65.go:8 +0x52
exit status 2
Why ?
Wrapping c <-
in a goroutine
makes the example run as we expected
package main
import "fmt"
func main() {
c := make(chan int)
go func(){
c <- 1
}()
fmt.Println(<-c)
}
Again, why ?
Please, I need deep explanation , not just how to eliminate the deadlock and fix the code.
From the documentation :
If the channel is unbuffered, the sender blocks until the receiver has received the value. If the channel has a buffer, the sender blocks only until the value has been copied to the buffer; if the buffer is full, this means waiting until some receiver has retrieved a value.
Said otherwise :
This line
c <- 1
blocks because the channel is unbuffered. As there's no other goroutine to receive the value, the situation can't resolve, this is a deadlock.
You can make it not blocking by changing the channel creation to
c := make(chan int, 1)
so that there's room for one item in the channel before it blocks.
But that's not what concurrency is about. Normally, you wouldn't use a channel without other goroutines to handle what you put inside. You could define a receiving goroutine like this :
func main() {
c := make(chan int)
go func() {
fmt.Println("received:", <-c)
}()
c <- 1
}