```
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
```
1、两个goroutine中的代码,在互相等待 chan 的值
`number` 和 `letter` 永远不会接收到数据,导致 numberDone 和 letterDone 也永远不会接收到数据。
```go
case <-number: {
fmt.Print(i)
i++
fmt.Print(i)
i++
letter <- true
break
}
```
```go
case <-letter: {
fmt.Print(string(i))
i++
fmt.Print(string(i))
i++
number <- true
break
}
```
2、发送到 chan 的数据,没有被接收。
main 中最后 `number <- true` ,发送给 number 了一个true,没有被接收。
使用如下代码就不会崩溃:
```
number <- true
fmt.Println("number: ", <- number)
```
#2
更多评论
```go
package main
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++
if i != 29 {
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
}
```
#1
Solved. letterDone 被读出之后,第二个goroutine完全退出,第一个goroutine阻塞在了letter <- true,主线程阻塞在了<- numberDone。@StoneFlying's answer solved this dead lock.
#3