Reputation: 179
case1
package main
func main() {
dogChan := make(chan int)
dogChan <- 1
}
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/Users/xuzhongwei/Source/awesomeProject/main.go:5 +0x50
case2
package main
func main() {
dogChan := make(chan int)
go func(ch chan int) {
}(dogChan)
dogChan <- 1
}
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/Users/xuzhongwei/Source/awesomeProject/main.go:9 +0x72
case3
package main
func main() {
dogChan := make(chan int)
go func(ch chan int) {
<- ch
}(dogChan)
dogChan <- 1
}
case4
package main
func main() {
dogChan := make(chan int)
go func(ch chan int) {
<- ch
}(dogChan)
dogChan <- 1
dogChan <- 2
}
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/Users/xuzhongwei/Source/awesomeProject/main.go:10 +0x90
case5
package main
func main() {
dogChan := make(chan int)
go func(ch chan int) {
for {
select {
case <- ch:
}
}
}(dogChan)
dogChan <- 1
dogChan <- 2
dogChan <- 3
dogChan <- 4
dogChan <- 5
}
Could anyone tell me why case1, case2 got errors while case3 is ok? In case1 my guess is that dogChan is not used in goroutine so it is treated to be closed. In case2 my guess is that although dogChan is passed in goroutine but it is not used in goroutine so it is treated to be closed
Could anyone tell me why case4 got errors while case5 is ok?
Upvotes: 3
Views: 1140
Reputation: 4444
Golang expects program to read message(s) placed into channel.
Consumer (reader) needs to drain (read) all messages from channel, either using simple for-read, or for-select. Channel send and receive both block until sender and receiver are ready.
// for range over channel
for msg := range ch {
// process msg
}
// for select
done := false
for !done {
select {
case msg := <-ch: {
// process msg
}
case ch == nil: {
done = true
}
}
}
// producer should close channel
close(ch)
Note:
Upvotes: 4
Reputation: 85710
Why do you think thats happening in case1
and case2
? The channels are meant to behave as a synchronisation primitive between a sender and receiver. You have a sender sending on a channel, dogChan
but none is receiving on it.
Without a receiving goroutine or a receive operation on a goroutine, the sender simply blocks (being a unbuffered channel)
Same problem on case4
, you have two sends on the channel, but a single receive on the goroutine. The dogChan <- 2
will block forever. In case5
, if your intention was to read from the channel, simply use a range
loop to iterate over the successive values sent over it.
Upvotes: 5