我在 Go Playground 中運行此代碼:https ://play.golang.org/p/1gqgXZXDhsF但它以死鎖結束: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 個(記錄器)只是坐著等待通道上發送給它的任何內容。當 4 個讀取器之一從通道獲取輸入時,它應該觸發 select 語句中的“case”,然后嘗試將該數據發送到記錄器通道。我對頻道還很陌生。我了解什么是死鎖以及可能發生死鎖的某些情況,尤其是在使用無緩沖通道時。但這在我看來應該有效。在此先感謝您的幫助。
1 回答

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