为啥以下代码会产生deadlock?

linture · · 914 次点击
stayfoo
stay hungry stay foolish
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