這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
最近看了下Go語言並寫了些範例程式碼,在用到channel的時候報了個奇怪的錯誤然後退出:
"fatal error: all goroutines are asleep - deadlock!"
在stackoverflow上搜到:http://stackoverflow.com/questions/8246065/all-goroutines-are-asleep-deadlock-error
查了查,出錯的代碼如下:
func chanFunc(c chan int, d chan int) { i := 0 for { select { case v, ok := <- c: if ok { fmt.Printf("channel c get %d\n", v) c <- v i++ if i >= 2 { break } } else { fmt.Println("channel C get fail") } case v, ok := <- d: if ok { fmt.Printf("channel d get %d\n", v) d <- v i++ if i >= 2 { break } } else { fmt.Println("channel D get fail") } } }}
c := make(chan int)d := make(chan int)//c <- 1go chanFunc(c, d)//write to channelc <- 1d <- 2cv := <- cdv := <- dfmt.Printf("cv = %d\n", cv)fmt.Printf("dv = %d\n", dv)
在chanFunc函數中如果管道c收到資料的話就會馬上將其返回,但此時主線程(暫且這麼稱呼)中在向管道d發送資料,結果就是:
1 主線程在等管道d
2 chanFunc在等管道c
3 c在等主線程接收
然後整個程式死結,導致退出。
程式中死結是常見的錯誤,不過採取直接退出的方式還是第一次碰到過,大概是《Unix編程藝術》中所說的那樣:“出現異常時,馬上退出並給出足夠錯誤資訊”。