I can't understand why the following code resulting in deadlock...anyone can help me?
In what conditions, channel will go into deadlock? I am really confused...
The following code is to print letters and numbers in this order "12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ2728" I want use channel to achieve this goal, but got deadlock. when removing numberDone channel, it goes OK.
import (
"fmt"
)
func main() {
AlterPrint()
}
// POINT: communicate between goroutines by channel
func AlterPrint(){
letter, number := make(chan bool), make(chan bool)
letterDone := make(chan bool)
numberDone := make(chan bool)
go func() {
i := 1
for {
if i > 28 {
numberDone <- true
return
}
select{
case <-number: {
fmt.Print(i)
i++
fmt.Print(i)
i++
letter <- true
break
}
default: {
break
}
}
}
}()
go func(){
i := 'A'
for {
if i > 'Z' {
letterDone <- true
return
}
select{
case <-letter: {
fmt.Print(string(i))
i++
fmt.Print(string(i))
i++
number <- true
break
}
default: {
break
}
}
}
}()
number <- true
<- letterDone
<- numberDone
}```
I expect the output of "12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ2728",
but the actual output is
goroutine 1 [chan receive]:
main.AlterPrint()
/tmp/54841538.go:66 +0x183
main.main()
/tmp/54841538.go:7 +0x14
goroutine 5 [chan send]:
main.AlterPrint.func1(0xc82000c240, 0xc82000c180, 0xc82000c120)
/tmp/54841538.go:31 +0x25a
created by main.AlterPrint
/tmp/54841538.go:40 +0xde
exit status 2
It should actually print what you expected and then deadlock. The second goroutine finishes everything, sends letterdone and terminates. At that point, main starts waiting at numberdone. The first goroutine prints the last two numbers, and starts waiting at letter<-true. That's the deadlock, at this point nothing can move forward. Try using fmt.Println instead of Print, maybe because of buffering it is not printing everything.