2 回答

TA貢獻1776條經驗 獲得超12個贊
OP更新問題后更新答案
您可以只循環地圖中的所有鍵,也許還有另一個 goroutine 不斷循環所有鍵。顯然,如果一個鍵沒有被初始化,那么它就不會出現在 for range 循環中。對于每個鍵,您可以啟動一個監聽的 goroutine,這樣它就不會阻塞,或者您可以使用緩沖通道,這樣它們就不會阻塞到緩沖區限制。您也可以最好使用 waitGroup,而不是 time.Sleep(),這些僅用于這個簡單的示例。
package main
import (
"fmt"
"time"
)
func main() {
m := make(map[int]chan string)
go func() {
m[0] = make(chan string)
m[0] <- "abab"
}()
time.Sleep(time.Second * 1) //sleep so the above goroutine initializes the key 0 channel
for key := range m{ //loop on all non-nil keys
fmt.Println(key)
go func(k int){ // goroutine to listen on this channel
fmt.Println(<- m[k])
}(key)
}
time.Sleep(time.Second * 1) //sleep so u can see the effects of the channel recievers
}
舊答案
流量就是這樣。主 goroutine 啟動。地圖已創建。主 goroutine 遇到另一個 goroutine。它產生了 goroutine 并繼續它的生活。然后遇到這條線,fmt.Println(<-m[0]),這是一個問題,因為地圖確實初始化了,但是地圖本身的通道沒有初始化!當主 goroutine 到達fmt.Println(<-m[0])時,另一個 goroutine 還沒有初始化通道!所以這是一個簡單的修復,只需在生成 goroutine 之前初始化通道,你就可以開始了!
package main
import "fmt"
func main() {
m := make(map[int]chan string)
m[0] = make(chan string)
go func() {
m[0] <- "abab"
}()
fmt.Println(<-m[0])
}
編輯:請注意這fmt.Println(<-m[0])是阻塞的,這意味著如果在另一個 goroutine 中,您不在通道上發送,您也會陷入死鎖,因為您試圖在沒有人實際發送的情況下在通道上接收。

TA貢獻1880條經驗 獲得超4個贊
您需要同步通道的創建。
就目前而言,您的主線程到達時<-m[0]
仍然m[0]
是一個未初始化的通道,并且在未初始化的通道上接收永遠阻塞。
您的 go 例程創建了一個新通道并將其放入m[0]
,但主要的 go 例程已經在偵聽先前的零值。在這個新通道上發送也會永遠阻塞,因為它沒有讀取任何內容,所以所有 goroutine 都會阻塞。
要解決這個問題,請移到m[0] = make(chan string)
你的 go 例程之上,這樣它就會同步發生。
- 2 回答
- 0 關注
- 126 瀏覽
添加回答
舉報