我在 Go Playground 中運行此代碼:https ://play.golang.org/p/1gqgXZXDhsF但它以死鎖結(jié)束:package mainimport ( "fmt" "time")func createFakeReadData(r map[int]chan string, n int) { for { time.Sleep(time.Duration(n - 1) * time.Second) r[n] <- string(n) }}func log(l <-chan string) { fmt.Println(<-l)}func main() { logChan := make(chan string) go log(logChan) rChanMap := make(map[int]chan string) rChanMap[5] = make(chan string) rChanMap[6] = make(chan string) rChanMap[7] = make(chan string) rChanMap[8] = make(chan string) go createFakeReadData(rChanMap, 5) go createFakeReadData(rChanMap, 6) go createFakeReadData(rChanMap, 7) go createFakeReadData(rChanMap, 8) for { var f string select { case f = <-rChanMap[5]: logChan <- f case f = <-rChanMap[6]: logChan <- f case f = <-rChanMap[7]: logChan <- f case f = <-rChanMap[8]: logChan <- f } }}fatal error: all goroutines are asleep - deadlock!我有 5 個 goroutine 和一個 main 中的 select 語句,它控制其中的 4 個(讀取器)。第 5 個(記錄器)只是坐著等待通道上發(fā)送給它的任何內(nèi)容。當(dāng) 4 個讀取器之一從通道獲取輸入時,它應(yīng)該觸發(fā) select 語句中的“case”,然后嘗試將該數(shù)據(jù)發(fā)送到記錄器通道。我對頻道還很陌生。我了解什么是死鎖以及可能發(fā)生死鎖的某些情況,尤其是在使用無緩沖通道時。但這在我看來應(yīng)該有效。在此先感謝您的幫助。
1 回答

慕碼人8056858
TA貢獻1803條經(jīng)驗 獲得超6個贊
createFakeReadData
正在無休止地將字符串發(fā)送到像rChanMap[5]
. 但log
你只從輸出通道接收一次:
func log(l <-chan string) { fmt.Println(<-l) }
由于您創(chuàng)建的所有通道都是無緩沖的,如果沒有 goroutine 從輸出通道接收數(shù)據(jù)logChan
,其他 goroutine 將永遠阻止嘗試發(fā)送給它。
您可能希望將log
函數(shù)更改為:
func log(l <-chan string) { for m := range l { fmt.Println(m) } }
這樣它就會從通道接收信息,直到通道關(guān)閉為止。
順便說一句,一些免費建議:
string(n)
不將整數(shù)轉(zhuǎn)換為字符串,嘗試搜索正確的方法來執(zhí)行此操作當(dāng)您創(chuàng)建通道時,您應(yīng)該考慮何時應(yīng)該關(guān)閉它,在您的代碼中沒有通道被關(guān)閉
詳細了解緩沖通道和非緩沖通道之間的區(qū)別
- 1 回答
- 0 關(guān)注
- 174 瀏覽
添加回答
舉報
0/150
提交
取消